Skip to content

Instantly share code, notes, and snippets.

Created May 31, 2013 07:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/5683363 to your computer and use it in GitHub Desktop.
Save anonymous/5683363 to your computer and use it in GitHub Desktop.
compile: "g++ -o ko -O2 -Wall main.cpp"
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <stdint.h>
#include <time.h>
namespace example {
enum type_t { TYPE_A, TYPE_B, TYPE_C, TYPE_D };
template <size_t Size>
struct data
{
uint8_t val[Size];
uint16_t acc;
template <typename T>
inline void visit(T& visitor)
{
visitor(*this);
}
};
typedef data<3> data_a;
typedef data<4> data_b;
typedef data<5> data_c;
typedef data<6> data_d;
struct element_type {
type_t type;
union
{
data_a a;
data_b b;
data_c c;
data_d d;
} data;
};
typedef std::vector<element_type> container;
// sum val into acc
struct calculator
{
template <size_t Size>
inline void operator()(data<Size>& item)
{
item.acc = 0;
for (size_t index = 0; index < Size; ++index)
item.acc += item.val[index];
}
};
// fill data with random values
struct generator
{
template <size_t Size>
inline void operator()(data<Size>& item)
{
uint8_t value = rand() % (256 - Size);
for (size_t index = 0; index < Size; ++index)
item.val[index] = value + index;
}
};
// print data to stdout
struct printer
{
template <size_t Size>
inline void operator()(data<Size>& item)
{
fprintf(stdout, "item<%zu>: ", Size);
for (size_t index = 0; index < Size; ++index)
fprintf(stdout, "%u ", unsigned(item.val[index]));
fprintf(stdout, "acc: %u\n", unsigned(item.acc));
}
};
// helper
template <typename T>
inline void visit(element_type& item, T& visitor)
{
switch (item.type)
{
case TYPE_A:
item.data.a.visit(visitor);
break;
case TYPE_B:
item.data.b.visit(visitor);
break;
case TYPE_C:
item.data.c.visit(visitor);
break;
case TYPE_D:
item.data.d.visit(visitor);
break;
default:
throw std::runtime_error("internal error");
}
}
// per element_type functors
struct create_random_element
{
generator visitor;
inline void operator()(element_type& item)
{
item.type = type_t(rand() % 4);
visit(item, visitor);
}
};
struct calculate_data
{
calculator visitior;
inline void operator()(element_type& item)
{
visit(item, visitior);
}
};
struct print_data
{
printer visitior;
inline void operator()(element_type& item)
{
visit(item, visitior);
}
};
// return timestamp in usecs
inline uint64_t current_timestamp()
{
timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
return 0;
return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
}
} /* namespace example */
int main(int argc, char* argv[])
{
size_t count = 4000;
uint64_t exec_time = 0;
try
{
uint64_t start_timestamp = example::current_timestamp();
example::container container(count);
std::for_each(container.begin(), container.end(), example::create_random_element());
std::for_each(container.begin(), container.end(), example::calculate_data());
//std::for_each(container.begin(), container.end(), example::print_data());
exec_time = example::current_timestamp() - start_timestamp;
}
catch (const std::exception& e)
{
fprintf(stderr, "FATAL: %s\n", e.what());
}
fprintf(stdout, "element_count: %zu\n", count);
fprintf(stdout, "element size: %zu\n", sizeof(example::element_type));
fprintf(stdout, "total execution time: %u us\n", unsigned(exec_time));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment