Skip to content

Commit 5f1aa85

Browse files
committed
Add @lindahua 's libm benchmark.
1 parent 3ee2a6e commit 5f1aa85

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

test/libm-bench.cpp

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
// Benchmark on libm functions
2+
3+
#include <math.h>
4+
#include <sys/time.h>
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
8+
9+
// Timing facilities
10+
11+
#ifdef __MACH__
12+
13+
#include <mach/mach_time.h>
14+
15+
class stimer
16+
{
17+
public:
18+
typedef uint64_t time_type;
19+
20+
stimer()
21+
{
22+
::mach_timebase_info(&m_baseinfo);
23+
}
24+
25+
time_type current() const
26+
{
27+
return ::mach_absolute_time();
28+
}
29+
30+
double span(const time_type& t0, const time_type& t1) const
31+
{
32+
uint64_t d = (m_baseinfo.numer * (t1 - t0)) / m_baseinfo.denom;
33+
return static_cast<double>(d) / 1.0e9;
34+
}
35+
36+
private:
37+
mach_timebase_info_data_t m_baseinfo;
38+
};
39+
40+
#else
41+
42+
class stimer
43+
{
44+
public:
45+
typedef timespec time_type;
46+
47+
time_type current() const
48+
{
49+
time_type t;
50+
::clock_gettime(CLOCK_REALTIME, &t);
51+
return t;
52+
}
53+
54+
double span(const time_type& t0, const time_type& t1) const
55+
{
56+
return double(t1.tv_sec - t0.tv_sec) +
57+
double(t1.tv_nsec - t0.tv_nsec) * 1.0e-9;
58+
}
59+
};
60+
61+
#endif
62+
63+
64+
inline double sec2mps(double s, long n)
65+
{
66+
return n / (s * 1e6);
67+
}
68+
69+
70+
const long ARR_LEN = 1024;
71+
72+
double a[ARR_LEN];
73+
double b[ARR_LEN];
74+
double r[ARR_LEN];
75+
76+
#define TFUN1(FNAME) \
77+
void test_##FNAME(long n) { \
78+
for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \
79+
stimer tm; \
80+
stimer::time_type t0 = tm.current(); \
81+
for(int i = 0; i < n; ++i) { \
82+
for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j]); \
83+
} \
84+
double s = tm.span(t0, tm.current()); \
85+
double mps = sec2mps(s, n * ARR_LEN); \
86+
printf(" %-8s: %7.4f MPS\n", #FNAME, mps); }
87+
88+
#define TFUN2(FNAME) \
89+
void test_##FNAME(long n) { \
90+
for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \
91+
stimer tm; \
92+
stimer::time_type t0 = tm.current(); \
93+
for(int i = 0; i < n; ++i) { \
94+
for (int j = 0; j < ARR_LEN; ++j) r[j] = FNAME(a[j], b[j]); \
95+
} \
96+
double s = tm.span(t0, tm.current()); \
97+
double mps = sec2mps(s, n * ARR_LEN); \
98+
printf(" %-8s: %7.4f MPS\n", #FNAME, mps); }
99+
100+
101+
#define TCALL(FNAME) test_##FNAME(20000)
102+
103+
// define benchmark functions
104+
105+
TFUN2(pow)
106+
TFUN2(hypot)
107+
108+
TFUN1(exp)
109+
TFUN1(log)
110+
TFUN1(log10)
111+
TFUN1(sin)
112+
TFUN1(cos)
113+
TFUN1(tan)
114+
TFUN1(asin)
115+
TFUN1(acos)
116+
TFUN1(atan)
117+
TFUN2(atan2)
118+
119+
int main(int argc, char *argv[])
120+
{
121+
// initialize array contents
122+
for (int i = 0; i < ARR_LEN; ++i)
123+
{
124+
a[i] = rand() / (double) RAND_MAX;
125+
b[i] = rand() / (double) RAND_MAX;
126+
}
127+
128+
TCALL(pow);
129+
TCALL(hypot);
130+
TCALL(exp);
131+
TCALL(log);
132+
TCALL(log10);
133+
TCALL(sin);
134+
TCALL(cos);
135+
TCALL(tan);
136+
TCALL(asin);
137+
TCALL(acos);
138+
TCALL(atan);
139+
TCALL(atan2);
140+
141+
return 0;
142+
}

0 commit comments

Comments
 (0)