Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
benchmark.hpp
Go to the documentation of this file.
1#pragma once
7#if defined(_MSC_VER) && (MSC_VER <= 1500)
8 #include <cybozu/inttype.hpp>
9#else
10 #include <stdint.h>
11#endif
12#include <stdio.h>
13
14#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
15 #define CYBOZU_BENCH_USE_RDTSC
16#endif
17#ifdef CYBOZU_BENCH_USE_RDTSC
18#ifdef _MSC_VER
19 #include <intrin.h>
20#endif
21#else
22 #include <cybozu/time.hpp>
23#endif
24
25namespace cybozu {
26
27#ifdef CYBOZU_BENCH_USE_RDTSC
28class CpuClock {
29public:
30 static inline uint64_t getRdtsc()
31 {
32#ifdef _MSC_VER
33 return __rdtsc();
34#else
35 unsigned int eax, edx;
36 __asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx));
37 return ((uint64_t)edx << 32) | eax;
38#endif
39 }
40 CpuClock()
41 : clock_(0)
42 , count_(0)
43 {
44 }
45 void begin()
46 {
47 clock_ -= getRdtsc();
48 }
49 void end()
50 {
51 clock_ += getRdtsc();
52 count_++;
53 }
54 int getCount() const { return count_; }
55 uint64_t getClock() const { return clock_; }
56 void clear() { count_ = 0; clock_ = 0; }
57 void put(const char *msg = 0, int N = 1) const
58 {
59 double t = getClock() / double(getCount()) / N;
60 if (msg && *msg) printf("%s ", msg);
61 if (t > 1e6) {
62 printf("%7.3fMclk", t * 1e-6);
63 } else if (t > 1e3) {
64 printf("%7.3fKclk", t * 1e-3);
65 } else {
66 printf("%6.2f clk", t);
67 }
68 if (msg && *msg) printf("\n");
69 }
70 // adhoc constatns for CYBOZU_BENCH
71 static const int loopN1 = 1000;
72 static const int loopN2 = 1000000;
73 static const uint64_t maxClk = (uint64_t)3e8;
74private:
75 uint64_t clock_;
76 int count_;
77};
78#else
79class CpuClock {
80 cybozu::Time t_;
81 uint64_t clock_;
82 int count_;
83public:
84 CpuClock() : clock_(0), count_(0) { t_.setTime(0, 0); }
85 void begin()
86 {
87 if (count_ == 0) t_.setCurrentTime(); // start
88 }
89 /*
90 @note QQQ ; this is not same api as rdtsc version
91 */
92 void end()
93 {
94 cybozu::Time cur(true);
95 int diffSec = (int)(cur.getTime() - t_.getTime());
96 int diffMsec = cur.getMsec() - t_.getMsec();
97 const int diff = diffSec * 1000 + diffMsec;
98 clock_ = diff;
99 count_++;
100 }
101 int getCount() const { return count_; }
102 uint64_t getClock() const { return clock_; }
103 void clear() { t_.setTime(0, 0); clock_ = 0; count_ = 0; }
104 void put(const char *msg = 0, int N = 1) const
105 {
106 double t = getClock() / double(getCount()) / N;
107 if (msg && *msg) printf("%s ", msg);
108 if (t > 1) {
109 printf("%6.2fmsec", t);
110 } else if (t > 1e-3) {
111 printf("%6.2fusec", t * 1e3);
112 } else {
113 printf("%6.2fnsec", t * 1e6);
114 }
115 if (msg && *msg) printf("\n");
116 }
117 // adhoc constatns for CYBOZU_BENCH
118 static const int loopN1 = 1000000;
119 static const int loopN2 = 1000;
120 static const uint64_t maxClk = (uint64_t)500;
121};
122#endif
123
124namespace bench {
125
126static CpuClock g_clk;
127#ifdef __GNUC__
128 #define CYBOZU_UNUSED __attribute__((unused))
129#else
130 #define CYBOZU_UNUSED
131#endif
132static int CYBOZU_UNUSED g_loopNum;
133
134} // cybozu::bench
135/*
136 loop counter is automatically determined
137 CYBOZU_BENCH(<msg>, <func>, <param1>, <param2>, ...);
138 if msg == "" then only set g_clk, g_loopNum
139*/
140#define CYBOZU_BENCH(msg, func, ...) \
141{ \
142 const uint64_t maxClk = cybozu::CpuClock::maxClk; \
143 cybozu::CpuClock clk; \
144 for (int i = 0; i < cybozu::CpuClock::loopN2; i++) { \
145 clk.begin(); \
146 for (int j = 0; j < cybozu::CpuClock::loopN1; j++) { func(__VA_ARGS__); } \
147 clk.end(); \
148 if (clk.getClock() > maxClk) break; \
149 } \
150 if (msg && *msg) clk.put(msg, cybozu::CpuClock::loopN1); \
151 cybozu::bench::g_clk = clk; cybozu::bench::g_loopNum = cybozu::CpuClock::loopN1; \
152}
153
154/*
155 loop counter N is given
156 CYBOZU_BENCH_C(<msg>, <counter>, <func>, <param1>, <param2>, ...);
157 if msg == "" then only set g_clk, g_loopNum
158*/
159#define CYBOZU_BENCH_C(msg, _N, func, ...) \
160{ \
161 cybozu::CpuClock clk; \
162 clk.begin(); \
163 for (int j = 0; j < _N; j++) { func(__VA_ARGS__); } \
164 clk.end(); \
165 if (msg && *msg) clk.put(msg, _N); \
166 cybozu::bench::g_clk = clk; cybozu::bench::g_loopNum = _N; \
167}
168
169} // cybozu
#define CYBOZU_UNUSED
int getCount() const
static const int loopN1
static const int loopN2
void put(const char *msg=0, int N=1) const
static const uint64_t maxClk
uint64_t getClock() const
void put()
Definition gen_code.cpp:234
void diff(const std::string &a, const std::string &b)
Definition jmp.cpp:18
const int N
Definition quantize.cpp:54
unsigned __int64 uint64_t
Definition stdint.h:136
void bench()
Definition test_zm.cpp:848