#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/wait.h>
#define PI 3.14159265
void print_stats(const char *name, struct timespec tv0)
{
FILE *f;
char buf[256];
struct timespec tv;
int maj, min, in_heap=0;
unsigned long l;
size_t vm_size=0, vm_rss=0, vm_priv_dirty=0;
clock_gettime(CLOCK_REALTIME, &tv);
tv.tv_sec -= tv0.tv_sec;
if ((tv.tv_nsec -= tv0.tv_nsec) < 0) {
tv.tv_nsec += 1000000000;
tv.tv_sec--;
}
f = fopen("/proc/self/smaps", "rb");
if (f) while (fgets(buf, sizeof buf, f)) {
if (sscanf(buf, "%*lx-%*lx %*s %*lx %x:%x %*lu %*s", &maj, &min)==2)
in_heap = (!maj && !min && !strstr(buf, "---p") && (strstr(buf, "[heap]") || !strchr(buf, '[')));
if (in_heap) {
if (sscanf(buf, "Size: %lu", &l)==1) vm_size += l;
else if (sscanf(buf, "Rss: %lu", &l)==1) vm_rss += l;
else if (sscanf(buf, "Private_Dirty: %lu", &l)==1) vm_priv_dirty += l;
}
}
if (f) fclose(f);
printf(": %-15s : %ld.%.9ld : %-6zu : %-6zu : %-6zu :\n",
name, (long)tv.tv_sec, (long)tv.tv_nsec,
vm_size, vm_rss, vm_priv_dirty);
}
void run_bench(const char *name, double (*bench)(double), double param)
{
int k;
volatile double result;
struct timespec tv0;
pid_t p = fork();
if (p) {
int status;
wait(&status);
return;
}
clock_gettime(CLOCK_REALTIME, &tv0);
for (k = 0; k < 1000000; ++k) {
result = bench(param);
assert(!result || result);
}
print_stats(name, tv0);
exit(0);
}
void run_benchf(const char *name, float (*benchf)(float), float param)
{
int k;
volatile float result;
struct timespec tv0;
pid_t p = fork();
if (p) {
int status;
wait(&status);
return;
}
clock_gettime(CLOCK_REALTIME, &tv0);
for (k = 0; k < 1000000; ++k) {
result = benchf(param);
assert(!result || result);
}
print_stats(name ,tv0);
exit(0);
}
int main (int argc, char *argv[])
{
printf ("--------------------------------------------------------------------\n");
printf (": Trigonometric functions :\n");
printf ("--------------------------------------------------------------------\n");
printf (": Name : Time : Virt : Res : Dirty :\n");
printf ("--------------------------------------------------------------------\n");
run_bench ("sin", sin, 30.0*PI/180);
run_benchf("sinf", sinf, 30.0*PI/180);
run_bench ("cos", cos, 60.0*PI/180);
run_benchf("cosf", cosf, 60.0*PI/180);
run_bench ("tan", tan, 45.0*PI/180);
run_benchf("tanf", tanf, 45.0*PI/180);
run_bench ("asin", asin, 0.5);
run_benchf("asinf", asinf, 0.5);
run_bench ("acos", acos, 0.5);
run_benchf("acosf", acosf, 0.5);
run_bench ("atan", atan, 1.0);
run_benchf("atanf", atanf, 1.0);
printf ("--------------------------------------------------------------------\n");
printf (": Hyperbolic functions :\n");
printf ("--------------------------------------------------------------------\n");
run_bench ("sinh", sinh, 0.69314718056);
run_benchf("sinhf", sinhf, 0.69314718056);
run_bench ("cosh", cosh, 0.69314718056);
run_benchf("coshf", coshf, 0.69314718056);
run_bench ("tanh", tanh, 0.69314718056);
run_benchf("tanhf", tanhf, 0.69314718056);
run_bench ("asinh", asinh, 0.75);
run_benchf("asinhf", asinhf, 0.75);
run_bench ("acosh", acosh, 1.25);
run_benchf("acoshf", acoshf, 1.25);
run_bench ("atanh", atanh, 0.60);
run_benchf("atanhf", atanhf, 0.60);
printf ("--------------------------------------------------------------------\n");
printf (": Exponential and logarithmic functions :\n");
printf ("--------------------------------------------------------------------\n");
run_bench ("exp", exp, 5.0);
run_benchf("expf", expf, 5.0);
run_bench ("exp1m", expm1, 5.0);
run_benchf("exp1mf", expm1f, 5.0);
run_bench ("log", log, 5.5);
run_benchf("logf", logf, 5.5);
run_bench ("log10", log10, 1000.0);
run_benchf("log10f", log10f, 1000.0);
run_bench ("log1p", log1p, 0.05);
run_benchf("log1pf", log1pf, 0.05);
printf ("--------------------------------------------------------------------\n");
printf (": Power functions :\n");
printf ("--------------------------------------------------------------------\n");
run_bench ("sqrt", sqrt, 1024.0);
run_benchf("sqrtf", sqrtf, 1024.0);
run_bench ("cbrt", cbrt, 32768.0);
run_benchf("cbrtf", cbrtf, 32768.0);
printf ("--------------------------------------------------------------------\n\n");
return 0;
}