Change how mixed read/write workloads are done in mixedbench
[bluesky.git] / microbench / mixedbench.c
index 81e63cf..0447fd1 100644 (file)
@@ -9,6 +9,8 @@
  *   Threads
  *   Benchmark duration (seconds)
  *   Target operations per second (aggregate across all threads)
+ *   Interval count (how many times to report results during the run)
+ *   Directory size (number of files per numbered subdirectory)
  */
 
 #include <errno.h>
 #include <unistd.h>
 #include <math.h>
 
-int opt_filesize, opt_filecount, opt_threads, opt_duration;
+int opt_filesize, opt_filecount, opt_threads, opt_duration, opt_intervals, opt_dirsize;
 double opt_writeratio, opt_ops;
 
+int write_threads;
+
 struct thread_state {
     pthread_t thread;
     pthread_mutex_t lock;
@@ -88,13 +92,13 @@ void benchmark_op(struct thread_state *ts)
 
     start = now_hires();
 
-    char filename[64];
-    sprintf(filename, "t%d/%d", ts->thread_num, get_random(opt_filecount));
-
-    double r = get_random(1000000) / 1e6;
+    char filename[256];
+    int n = get_random(opt_filecount);
+    int n1 = n / opt_dirsize, n2 = n % opt_dirsize;
 
-    if (r >= opt_writeratio) {
+    if (ts->thread_num >= write_threads) {
         /* Read */
+        sprintf(filename, "t%d/%d/%d", ts->thread_num - write_threads, n1, n2);
         FILE *f = fopen(filename, "rb");
         if (f == NULL) {
             perror("fopen");
@@ -113,6 +117,7 @@ void benchmark_op(struct thread_state *ts)
         pthread_mutex_unlock(&ts->lock);
     } else {
         /* Write */
+        sprintf(filename, "t%d/%d/%d", ts->thread_num, n1, n2);
         FILE *f = fopen(filename, "wb");
         if (f == NULL) {
             perror("fopen");
@@ -192,6 +197,7 @@ void reset_stats(int print, double duration)
         write_time2 += threads[i].write_time2;
         threads[i].read_count = threads[i].write_count = 0;
         threads[i].read_time = threads[i].write_time = 0;
+        threads[i].read_time2 = threads[i].write_time2 = 0;
         pthread_mutex_unlock(&threads[i].lock);
     }
 
@@ -203,12 +209,13 @@ void reset_stats(int print, double duration)
                write_count / duration, write_time / write_count,
                stddev(write_time, write_time2, write_count));
         printf("\n");
+        fflush(stdout);
     }
 }
 
 int main(int argc, char *argv[])
 {
-    if (argc != 7) {
+    if (argc != 9) {
         fprintf(stderr, "Usage: TODO\n");
         return 1;
     }
@@ -219,18 +226,26 @@ int main(int argc, char *argv[])
     opt_threads = atoi(argv[4]);
     opt_duration = atoi(argv[5]);
     opt_ops = atof(argv[6]);
+    opt_intervals = atoi(argv[7]);
+    opt_dirsize = atoi(argv[8]);
 
     srandom(time(NULL));
 
     start_time = now_hires();
 
+    /* Partition threads into those that should do reads and those for writes,
+     * as close as possible to the desired allocation. */
+    write_threads = (int)round(opt_threads * opt_writeratio);
+    fprintf(stderr, "Using %d threads for reads, %d for writes\n",
+            opt_threads - write_threads, write_threads);
+
     for (int i = 0; i < opt_threads; i++) {
         launch_thread(i);
     }
 
-    for (int i = 0; i < 4; i++) {
-        sleep_micros(opt_duration * 1000000 / 4);
-        reset_stats(1, opt_duration / 4.0);
+    for (int i = 0; i < opt_intervals; i++) {
+        sleep_micros(opt_duration * 1000000 / opt_intervals);
+        reset_stats(1, (double)opt_duration / opt_intervals);
     }
 
     return 0;