X-Git-Url: https://git.saurik.com/apple/libdispatch.git/blobdiff_plain/d4e0f4aade4f18254fb326a5aa6c521fad1930d2..24954c793bca436d612851de3a460c72ef1f7b6d:/testing/float_parsing.c diff --git a/testing/float_parsing.c b/testing/float_parsing.c new file mode 100644 index 0000000..716bf50 --- /dev/null +++ b/testing/float_parsing.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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; +}