// -*-C++-*- #define NDEBUG #include "vecmathlib.h" #include #include #include #include #include using namespace std; typedef unsigned long long ticks; inline ticks getticks() { ticks a, d; asm volatile("rdtsc" : "=a" (a), "=d" (d)); return a | (d << 32); } inline double elapsed(ticks t1, ticks t0) { return t1-t0; } double get_sys_time() { timeval tp; gettimeofday(&tp, NULL); return tp.tv_sec + 1.0e-6 * tp.tv_usec; } double measure_tick() { ticks const rstart = getticks(); double const wstart = get_sys_time(); while (get_sys_time() - wstart < 0.1) { // do nothing, just wait } ticks const rend = getticks(); double const wend = get_sys_time(); assert(wend-wstart >= 0.09); return (wend - wstart) / elapsed(rend, rstart); } double global_result = 0.0; template void save_result(realvec_t result) { for (int i=0; i inline T identity(T x) { return x; } #define DECLARE_FUNCTOR(func) \ template \ struct functor_##func { \ T operator()(T x) { return func(x); } \ } DECLARE_FUNCTOR(identity); DECLARE_FUNCTOR(sqrt); DECLARE_FUNCTOR(exp); DECLARE_FUNCTOR(log); DECLARE_FUNCTOR(sin); DECLARE_FUNCTOR(cos); DECLARE_FUNCTOR(atan); template double bench_func() { realvec_t x0, dx; for (int i=0; i void bench() { cout << "identity(" << realvec_t::name() << "):" << flush; double const cycles_identity = bench_func>(); cout << " " << cycles_identity << " cycles\n"; cout << "sqrt(" << realvec_t::name() << "):" << flush; double const cycles_sqrt = bench_func>(); cout << " " << cycles_sqrt - cycles_identity << " cycles\n"; cout << "exp(" << realvec_t::name() << "):" << flush; double const cycles_exp = bench_func>(); cout << " " << cycles_exp - cycles_identity << " cycles\n"; cout << "log(" << realvec_t::name() << "):" << flush; double const cycles_log = bench_func>(); cout << " " << cycles_log - cycles_identity << " cycles\n"; cout << "sin(" << realvec_t::name() << "):" << flush; double const cycles_sin = bench_func>(); cout << " " << cycles_sin - cycles_identity << " cycles\n"; cout << "cos(" << realvec_t::name() << "):" << flush; double const cycles_cos = bench_func>(); cout << " " << cycles_cos - cycles_identity << " cycles\n"; cout << "atan(" << realvec_t::name() << "):" << flush; double const cycles_atan = bench_func>(); cout << " " << cycles_atan - cycles_identity << " cycles\n"; } int main(int argc, char** argv) { using namespace vecmathlib; cout << "Benchmarking math functions:\n" << "\n"; #ifdef VECMATHLIB_HAVE_VEC_FLOAT_1 bench>(); #endif #ifdef VECMATHLIB_HAVE_VEC_FLOAT_4 bench>(); #endif #ifdef VECMATHLIB_HAVE_VEC_FLOAT_8 bench>(); #endif cout << "\n"; #ifdef VECMATHLIB_HAVE_VEC_DOUBLE_1 bench>(); #endif #ifdef VECMATHLIB_HAVE_VEC_DOUBLE_2 bench>(); #endif #ifdef VECMATHLIB_HAVE_VEC_DOUBLE_4 bench>(); #endif cout << "\n" << "Outputting global result to prevent optimisation: " << global_result << "\n"; return 0; }