Permalink
Browse files

Revision 1: Created. Converted all non-inlined versions from Java to C++

  • Loading branch information...
pzemtsov committed May 6, 2014
1 parent f60ee7a commit 456c11dddc868b21a3282472010d63f1e1826a6b
Showing with 252 additions and 0 deletions.
  1. +219 −0 e1.cpp
  2. +33 −0 timer.h
View
219 e1.cpp
@@ -0,0 +1,219 @@
+/** Revision 1: Created. Converted all non-inlined versions from Java to C++
+ */
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <iostream>
+#include <typeinfo>
+
+#include "timer.h"
+
+typedef unsigned char byte;
+
+static const unsigned NUM_TIMESLOTS = 32;
+static const unsigned DST_SIZE = 64;
+static const unsigned SRC_SIZE = NUM_TIMESLOTS * DST_SIZE;
+static const unsigned ITERATIONS = 1000000;
+static const unsigned REPETITIONS = 2;
+
+using namespace std;
+
+class Demux
+{
+public:
+ virtual void demux (const byte * src, unsigned src_length, byte ** dst) const = 0;
+};
+
+class Reference : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ unsigned dst_pos = 0;
+ unsigned dst_num = 0;
+ for (unsigned src_pos = 0; src_pos < src_length; src_pos++) {
+ dst [dst_num][dst_pos] = src [src_pos];
+ if (++ dst_num == NUM_TIMESLOTS) {
+ dst_num = 0;
+ ++ dst_pos;
+ }
+ }
+ }
+};
+
+class Src_First_1 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ unsigned src_pos = 0;
+ unsigned dst_pos = 0;
+ while (src_pos < src_length) {
+ for (unsigned dst_num = 0; dst_num < NUM_TIMESLOTS; ++ dst_num) {
+ dst [dst_num][dst_pos] = src [src_pos ++];
+ }
+ ++ dst_pos;
+ }
+ }
+};
+
+class Src_First_2 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ for (unsigned dst_pos = 0; dst_pos < src_length / NUM_TIMESLOTS; ++ dst_pos) {
+ for (unsigned dst_num = 0; dst_num < NUM_TIMESLOTS; ++ dst_num) {
+ dst [dst_num][dst_pos] = src [dst_pos * NUM_TIMESLOTS + dst_num];
+ }
+ }
+ }
+};
+
+class Src_First_3 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ for (unsigned i = 0; i < src_length; i++) {
+ dst [i % NUM_TIMESLOTS][i / NUM_TIMESLOTS] = src [i];
+ }
+ }
+};
+
+class Dst_First_1 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ for (unsigned dst_num = 0; dst_num < NUM_TIMESLOTS; ++ dst_num) {
+ for (unsigned dst_pos = 0; dst_pos < src_length / NUM_TIMESLOTS; ++ dst_pos) {
+ dst [dst_num][dst_pos] = src [dst_pos * NUM_TIMESLOTS + dst_num];
+ }
+ }
+ }
+};
+
+class Dst_First_2 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length % NUM_TIMESLOTS == 0);
+
+ unsigned dst_size = src_length / NUM_TIMESLOTS;
+ for (unsigned dst_num = 0; dst_num < NUM_TIMESLOTS; ++ dst_num) {
+ byte * d = dst [dst_num];
+ unsigned src_pos = dst_num;
+ for (unsigned dst_pos = 0; dst_pos < dst_size; ++ dst_pos) {
+ d[dst_pos] = src[src_pos];
+ src_pos += NUM_TIMESLOTS;
+ }
+ }
+ }
+};
+
+class Dst_First_3 : public Demux
+{
+public:
+ void demux (const byte * src, unsigned src_length, byte ** dst) const
+ {
+ assert (src_length == NUM_TIMESLOTS * DST_SIZE);
+
+ for (unsigned dst_num = 0; dst_num < NUM_TIMESLOTS; ++ dst_num) {
+ for (unsigned dst_pos = 0; dst_pos < DST_SIZE; ++ dst_pos) {
+ dst [dst_num][dst_pos] = src [dst_pos * NUM_TIMESLOTS + dst_num];
+ }
+ }
+ }
+};
+
+byte * generate ()
+{
+ byte * buf = new byte [SRC_SIZE];
+ srand (0);
+ for (unsigned i = 0; i < SRC_SIZE; i++) buf[i] = (byte) (rand () % 256);
+ return buf;
+}
+
+byte ** allocate_dst ()
+{
+ byte ** result = new byte * [NUM_TIMESLOTS];
+ for (unsigned i = 0; i < NUM_TIMESLOTS; i++) {
+ result [i] = new byte [DST_SIZE];
+ }
+ return result;
+}
+
+void delete_dst (byte ** dst)
+{
+ for (unsigned i = 0; i < NUM_TIMESLOTS; i++) {
+ delete dst [i];
+ }
+ delete dst;
+}
+
+void check (const Demux & demux)
+{
+ byte * src = generate ();
+ byte ** dst0 = allocate_dst ();
+ byte ** dst = allocate_dst ();
+ Reference().demux (src, SRC_SIZE, dst0);
+ demux.demux (src, SRC_SIZE, dst);
+ for (int i = 0; i < NUM_TIMESLOTS; i++) {
+ if (memcmp (dst0[i], dst[i], DST_SIZE)) {
+ cout << "Results not equal\n";
+ exit (1);
+ }
+ }
+ delete src;
+ delete_dst (dst0);
+ delete_dst (dst);
+}
+
+byte * src;
+byte ** dst;
+
+void measure (const Demux & demux)
+{
+ check (demux);
+
+ cout << typeid (demux).name() << ":";
+
+ for (unsigned loop = 0; loop < REPETITIONS; loop ++) {
+ uint64_t t0 = currentTimeMillis ();
+ for (int i = 0; i < ITERATIONS; i++) {
+ demux.demux (src, SRC_SIZE, dst);
+ }
+ uint64_t t = currentTimeMillis () - t0;
+ cout << " " << t;
+ }
+ cout << endl;
+}
+
+int main (void)
+{
+ src = generate ();
+ dst = allocate_dst ();
+
+ measure (Reference ());
+ measure (Src_First_1 ());
+ measure (Src_First_2 ());
+ measure (Src_First_3 ());
+ measure (Dst_First_1 ());
+ measure (Dst_First_2 ());
+ measure (Dst_First_3 ());
+
+ return 0;
+}
View
33 timer.h
@@ -0,0 +1,33 @@
+#include <stdint.h>
+
+#ifdef __linux__
+#include <ctime>
+#else
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+static uint64_t currentTimeMillis()
+{
+#ifdef _WIN32
+ const uint64_t EPOCH = 116444736000000000;
+
+ FILETIME fileTime;
+ GetSystemTimeAsFileTime (&fileTime);
+ uint64_t t = * (uint64_t*) &fileTime;
+ return (t-EPOCH) / 10000;
+#else
+#ifdef __linux__
+ timespec tse;
+ clock_gettime(CLOCK_REALTIME, &tse);
+ return (tse.tv_sec * 1000 + tse.tv_nsec * 1E-6);
+#else
+#error Only Linux and Win32 are supported
+#endif
+#endif
+}

0 comments on commit 456c11d

Please sign in to comment.