#include "bench.h" #include "lib_debug.h" /* * return micro-seconds / iteration at the the fraction point. * * some examples: * min = percent_point(values, size, 0.0) * 1st quartile = percent_point(values, size, 0.25) * median = percent_point(values, size, 0.5) * 3rd quartile = percent_point(values, size, 0.75) * max = percent_point(values, size, 1.0) * * the data points in the results structure are sorted from * largest to smallest, so we adjust the fraction accordingly. */ double percent_point(double fraction) { double t, r; result_t* results = get_results(); t = (1.0 - fraction) * (results->N - 1); if (t == floor(t)) { /* no interpolation */ r = results->v[(int)t].u / (double)results->v[(int)t].n; } else { /* percent point falls between two points, interpolate */ r = results->v[(int)t].u / (double)results->v[(int)t].n; r += results->v[(int)t+1].u / (double)results->v[(int)t+1].n; r /= 2.0; } return r; } void print_results(int details) { int i; result_t* results = get_results(); fprintf(stderr, "N=%d, t={", results->N); for (i = 0; i < results->N; ++i) { fprintf(stderr, "%.2f", (double)results->v[i].u/results->v[i].n); if (i < results->N - 1) fprintf(stderr, ", "); } fprintf(stderr, "}\n"); if (details) { fprintf(stderr, "\t/* %d {", results->N); for (i = 0; i < results->N; ++i) { fprintf(stderr, "%llu/%llu", results->v[i].u, results->v[i].n); if (i < results->N - 1) fprintf(stderr, ", "); } fprintf(stderr, "} */\n"); } } /* * Prints bandwidth (MB/s) quartile information * * bytes - bytes per iteration */ void bw_quartile(uint64 bytes) { fprintf(stderr, "%lu\t%e\t%e\t%e\t%e\t%e\n", (unsigned long)get_n(), (double)bytes / (1000000. * percent_point(0.00)), (double)bytes / (1000000. * percent_point(0.25)), (double)bytes / (1000000. * percent_point(0.50)), (double)bytes / (1000000. * percent_point(0.75)), (double)bytes / (1000000. * percent_point(1.00))); } /* * Prints latency (nano-seconds) quartile information * * n - number of operations per iteration */ void nano_quartile(uint64 n) { fprintf(stderr, "%lu\t%e\t%e\t%e\t%e\t%e\n", (unsigned long)get_n(), percent_point(0.00) * 1000. / (double)n, percent_point(0.25) * 1000. / (double)n, percent_point(0.50) * 1000. / (double)n, percent_point(0.75) * 1000. / (double)n, percent_point(1.00) * 1000. / (double)n); } /* * print the page|line|word offset for each link in the pointer chain. */ void print_mem(char* addr, size_t size, size_t line) { char* p; uint64 base, off; size_t pagesize = getpagesize(); base = (uint64)addr; for (p = addr; *(char**)p != addr; p = *(char**)p) { off = (uint64)p - base; fprintf(stderr, "\t%lu\t%lu\t%lu\n", (unsigned long)(off / pagesize), (unsigned long)((off % pagesize) / line), (unsigned long)((off % line) / sizeof(char*))); } } void check_mem(char* addr, size_t size) { char* p; size_t i; size_t max = size / sizeof(char*) + 1; for (p=addr, i=0; *(char**)p != addr && i < max; p = *(char**)p, i++) { if (p < addr || addr + size <= p) { fprintf(stderr, "check_mem: pointer out of range!\n"); } } if (*(char**)p != addr) { fprintf(stderr, "check_mem: pointer chain doesn't loop\n"); } }