Skip to content

Commit dde61e8

Browse files
committed
Add Cephes benchmark
1 parent e3d1368 commit dde61e8

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
2+
# VARIABLES #
3+
4+
ifndef VERBOSE
5+
QUIET := @
6+
endif
7+
8+
# Specify the path to Cephes:
9+
CEPHES ?=
10+
11+
# Specify a list of Cephes source files:
12+
CEPHES_SRC ?=
13+
14+
# Determine the OS:
15+
#
16+
# [1]: https://en.wikipedia.org/wiki/Uname#Examples
17+
# [2]: http://stackoverflow.com/a/27776822/2225624
18+
OS ?= $(shell uname)
19+
ifneq (, $(findstring MINGW,$(OS)))
20+
OS := WINNT
21+
else
22+
ifneq (, $(findstring MSYS,$(OS)))
23+
OS := WINNT
24+
else
25+
ifneq (, $(findstring CYGWIN,$(OS)))
26+
OS := WINNT
27+
endif
28+
endif
29+
endif
30+
31+
# Define the program used for compiling C source files:
32+
ifdef C_COMPILER
33+
CC := $(C_COMPILER)
34+
else
35+
CC := gcc
36+
endif
37+
38+
# Define the command-line options when compiling C files:
39+
CFLAGS ?= \
40+
-std=c99 \
41+
-O3 \
42+
-Wall \
43+
-pedantic
44+
45+
# Determine whether to generate [position independent code][1]:
46+
#
47+
# [1]: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options
48+
# [2]: http://stackoverflow.com/questions/5311515/gcc-fpic-option
49+
ifeq ($(OS), WINNT)
50+
fPIC ?=
51+
else
52+
fPIC ?= -fPIC
53+
endif
54+
55+
# List of C targets:
56+
c_targets := benchmark.out
57+
58+
59+
# TARGETS #
60+
61+
# Default target.
62+
#
63+
# This target is the default target.
64+
65+
all: $(c_targets)
66+
67+
.PHONY: all
68+
69+
70+
# Compile C source.
71+
#
72+
# This target compiles C source files.
73+
74+
$(c_targets): %.out: %.c
75+
$(QUIET) $(CC) $(CFLAGS) $(fPIC) -o $@ $(CEPHES_SRC) $< -lm
76+
77+
78+
# Run a benchmark.
79+
#
80+
# This target runs a benchmark.
81+
82+
run: $(c_targets)
83+
$(QUIET) ./$<
84+
85+
.PHONY: run
86+
87+
88+
# Perform clean-up.
89+
#
90+
# This target removes generated files.
91+
92+
clean:
93+
$(QUIET) -rm -f *.o *.out
94+
95+
.PHONY: clean
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/**
2+
* Benchmark Cephes `erf`.
3+
*/
4+
#include <stdlib.h>
5+
#include <stdio.h>
6+
#include <math.h>
7+
#include <sys/time.h>
8+
9+
#define NAME "erf"
10+
#define ITERATIONS 1000000
11+
#define REPEATS 3
12+
13+
/**
14+
* Define prototypes for external functions.
15+
*/
16+
extern double erf( double x );
17+
18+
/**
19+
* Prints the TAP version.
20+
*/
21+
void print_version() {
22+
printf( "TAP version 13\n" );
23+
}
24+
25+
/**
26+
* Prints the TAP summary.
27+
*
28+
* @param total total number of tests
29+
* @param passing total number of passing tests
30+
*/
31+
void print_summary( int total, int passing ) {
32+
printf( "#\n" );
33+
printf( "1..%d\n", total ); // TAP plan
34+
printf( "# total %d\n", total );
35+
printf( "# pass %d\n", passing );
36+
printf( "#\n" );
37+
printf( "# ok\n" );
38+
}
39+
40+
/**
41+
* Prints benchmarks results.
42+
*
43+
* @param elapsed elapsed time in seconds
44+
*/
45+
void print_results( double elapsed ) {
46+
double rate = (double)ITERATIONS / elapsed;
47+
printf( " ---\n" );
48+
printf( " iterations: %d\n", ITERATIONS );
49+
printf( " elapsed: %0.9f\n", elapsed );
50+
printf( " rate: %0.9f\n", rate );
51+
printf( " ...\n" );
52+
}
53+
54+
/**
55+
* Returns a clock time.
56+
*
57+
* @return clock time
58+
*/
59+
double tic() {
60+
struct timeval now;
61+
gettimeofday( &now, NULL );
62+
return (double)now.tv_sec + (double)now.tv_usec/1.0e6;
63+
}
64+
65+
/**
66+
* Generates a random double on the interval [0,1].
67+
*
68+
* @return random double
69+
*/
70+
double rand_double() {
71+
int r = rand();
72+
return (double)r / ( (double)RAND_MAX + 1.0 );
73+
}
74+
75+
/**
76+
* Runs a benchmark.
77+
*
78+
* @return elapsed time in seconds
79+
*/
80+
double benchmark() {
81+
double elapsed;
82+
double x;
83+
double y;
84+
double t;
85+
int i;
86+
87+
t = tic();
88+
for ( i = 0; i < ITERATIONS; i++ ) {
89+
x = ( 2.0*rand_double() ) - 1.0;
90+
y = erf( x );
91+
if ( y != y ) {
92+
printf( "should not return NaN\n" );
93+
break;
94+
}
95+
}
96+
elapsed = tic() - t;
97+
if ( y != y ) {
98+
printf( "should not return NaN\n" );
99+
}
100+
return elapsed;
101+
}
102+
103+
/**
104+
* Main execution sequence.
105+
*/
106+
int main( void ) {
107+
double elapsed;
108+
int i;
109+
110+
// Use the current time to seed the random number generator:
111+
srand( time( NULL ) );
112+
113+
print_version();
114+
for ( i = 0; i < REPEATS; i++ ) {
115+
printf( "# c::cephes::%s\n", NAME );
116+
elapsed = benchmark();
117+
print_results( elapsed );
118+
printf( "ok %d benchmark finished\n", i+1 );
119+
}
120+
print_summary( REPEATS, REPEATS );
121+
}

0 commit comments

Comments
 (0)