#include <dispatch/dispatch.h> #include <sys/types.h> #include <sys/param.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <assert.h> #include <string.h> #include <math.h> #define MAXLAPS (512 * 1024) static void test(size_t LAPS, char *nums) { uint64_t concurrent_cycles; uint64_t serial_cycles; char **result_strings; char *nums_off; double *results; size_t i; result_strings = calloc(1, sizeof(char *) * LAPS); assert(result_strings); results = calloc(1, sizeof(double) * LAPS); assert(results); printf("%zu random floats\n", LAPS); i = 0; nums_off = nums; do { result_strings[i] = nums_off; do { nums_off++; assert(*nums_off); } while (*nums_off != '\n'); i++; nums_off++; } while (i < LAPS); for (i = 0; i < LAPS; i++) { assert(result_strings[i]); } concurrent_cycles = dispatch_benchmark(10, ^{ dispatch_apply(LAPS, dispatch_get_concurrent_queue(0), ^(size_t idx) { results[idx] = strtod(result_strings[idx], NULL); }); }); for (i = 0; i < LAPS; i++) { assert(results[i]); } serial_cycles = dispatch_benchmark(10, ^{ size_t k = 0; do { results[k] = strtod(result_strings[k], NULL); k++; } while (k < LAPS); }); for (i = 0; i < LAPS; i++) { assert(results[i]); } printf( "\tserial cycles:\t%llu\n" "\tapply() cycles:\t%llu\n" "\tserial / concurrent: %.2Lf\n", serial_cycles, concurrent_cycles, (long double)serial_cycles / (long double)concurrent_cycles); free(result_strings); free(results); } int main(void) { char path[PATH_MAX] = "/tmp/random_floats_XXXXXX"; struct stat sb; double words[1000]; char buf[1024]; char *nums; int fd, rfd; size_t i, j; ssize_t r; rfd = open("/dev/random", O_RDONLY); assert(rfd != -1); fd = mkstemp(path); assert(fd != -1); r = unlink(path); assert(r != -1); i = 0; do { r = read(rfd, words, sizeof(words)); assert(r == sizeof(words)); for (j = 0; j < 1000; j++) { if (isnormal(words[j])) { r = write(fd, buf, snprintf(buf, sizeof(buf), "%.20e\n", words[j])); assert(r != -1); i++; } } } while (i < MAXLAPS); r = close(rfd); assert(r != -1); r = fstat(fd, &sb); assert(r != -1); nums = mmap(NULL, sb.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0); assert(nums != MAP_FAILED); for (i = MAXLAPS; i > 0; i /= 2) { test(i, nums); } r = munmap(nums, sb.st_size); assert(r != -1); r = close(fd); assert(r != -1); return 0; }