]> git.saurik.com Git - apple/libdispatch.git/blobdiff - testing/float_parsing.c
libdispatch-84.5.3.tar.gz
[apple/libdispatch.git] / testing / float_parsing.c
diff --git a/testing/float_parsing.c b/testing/float_parsing.c
new file mode 100644 (file)
index 0000000..716bf50
--- /dev/null
@@ -0,0 +1,136 @@
+#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;
+}