[DRBD-cvs] svn commit by phil - r2531 - branches/drbd-0.7/benchmark - More improvements to the io-latency-test program

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Fri Oct 13 16:46:58 CEST 2006


Author: phil
Date: 2006-10-13 16:46:58 +0200 (Fri, 13 Oct 2006)
New Revision: 2531

Modified:
   branches/drbd-0.7/benchmark/io-latency-test.c
Log:
More improvements to the io-latency-test program


Modified: branches/drbd-0.7/benchmark/io-latency-test.c
===================================================================
--- branches/drbd-0.7/benchmark/io-latency-test.c	2006-10-13 14:38:08 UTC (rev 2530)
+++ branches/drbd-0.7/benchmark/io-latency-test.c	2006-10-13 14:46:58 UTC (rev 2531)
@@ -34,6 +34,9 @@
 #include <time.h>
 #include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
+#define _GNU_SOURCE
+#include <getopt.h>
 
 #define MONITOR_TIME 300000
 // Check every 300 milliseconds. (3.33 times per second)
@@ -41,22 +44,29 @@
 #define RECORD_TIME 20000
 // Try to write a record every 20 milliseconds (50 per second)
 
+unsigned int monitor_time=MONITOR_TIME;
+unsigned int record_time=RECORD_TIME;
+unsigned long records=0;
+
 struct shared_data {
 	pthread_mutex_t mutex;
 	unsigned long record_nr;
 	unsigned int write_duration_us;
 	unsigned int write_duration_records;
+	double avg_write_duration;
 };
 
 void* wd_thread(void *arg)
 {
 	struct shared_data *data = (struct shared_data*) arg;
-	unsigned long last_record_nr=-1, current_record_nr;
+	unsigned long last_record_nr=-1, current_record_nr=0;
 	unsigned int avg_write,wd,wr;
+	double avg_write_duration;
+
 	enum { IO_RUNNING, IO_BLOCKED } io_state = IO_RUNNING;
 	
 	while(1) {
-		usleep(MONITOR_TIME); // sleep some milliseconds
+		usleep(monitor_time); // sleep some milliseconds
 
 		pthread_mutex_lock(&data->mutex);
 		current_record_nr = data->record_nr;
@@ -64,8 +74,11 @@
 		wr = data->write_duration_records;
 		data->write_duration_us = 0;
 		data->write_duration_records = 0;
+		avg_write_duration = data->avg_write_duration;
 		pthread_mutex_unlock(&data->mutex);
 
+		if( records && current_record_nr == records) break;
+
 		switch(io_state) {
 		case IO_RUNNING:
 			if(current_record_nr == last_record_nr) {
@@ -78,9 +91,11 @@
 				avg_write = wd/wr;
 
 				printf("Current record: %lu "
-				       "( AVG write duration %d.%02dms )\r",
+				       "( cur. write duration %d.%02dms; "
+				       "avg. wd. %.2fms)\r",
 				       current_record_nr,
-				       avg_write/1000,(avg_write%1000)/10);
+				       avg_write/1000,(avg_write%1000)/10,
+				       avg_write_duration/1000);
 				fflush(stdout);
 			}
 			last_record_nr = current_record_nr;
@@ -91,8 +106,20 @@
 			}
 		}
 	}
+	if(io_state == IO_RUNNING) printf("\n");
 }
 
+void usage(char *prgname)
+{
+	fprintf(stderr, "USAGE: %s [options] recordfile\n"
+		"  Available options:\n"
+		"   --records val         -n val\n"
+		"   --record-interval-ms  -r val\n"
+		"   --monitor-interval-ms -m val\n",
+		prgname);
+	exit(20);
+}
+
 int main(int argc, char** argv)
 {
 	pthread_t watch_dog;
@@ -102,17 +129,46 @@
 	struct timeval now_tv, then_tv;
 	struct tm now_tm;
 	int write_duration_us=0;
+	int min_wd=(1<<30), max_wd=0;
+	double avg_write_duration;
+	int avg_wd_nr=0,c;
 
 	struct shared_data data;
 
-	if(argc != 2) {
-		fprintf(stderr,"USAGE: %s recordfile\n",argv[0]);
-		return 10;
+	static struct option options[] = {
+		{"records", required_argument, 0, 'n'},
+		{"record-interval-ms", required_argument, 0, 'r'},
+		{"monitor-interval-ms", required_argument, 0, 'm'},
+		{0, 0, 0, 0 }
+	};
+
+	while (1) {
+		c = getopt_long(argc, argv, "n:r:m:", options, 0);
+		if (c == -1)
+			break;
+		switch (c) {
+		case 'n':
+			records = atol(optarg);
+			break;
+		case 'r':
+			record_time = atoi(optarg) * 1000;
+			break;
+		case 'm':
+			monitor_time = atoi(optarg) * 1000;
+			break;
+		default:
+			usage(argv[0]);
+		}
 	}
 
-	if(!(record_f = fopen(argv[1],"w"))) {
+	if(optind != argc-1) {
+		usage(argv[0]);
+	}
+
+	if(!(record_f = fopen(argv[optind],"w"))) {
 		perror("fopen:");
-		fprintf(stderr,"Failed to open '%s' for writing\n",argv[1]);
+		fprintf(stderr,"Failed to open '%s' for writing\n",
+			argv[optind]);
 		return 10;
 	}
 
@@ -136,7 +192,7 @@
 	data.write_duration_records = 1;
 	pthread_create(&watch_dog,NULL,wd_thread,&data);
 
-	for(;;record_nr++) {
+	for( ; !records || record_nr < records ; record_nr++) {
 		gettimeofday(&now_tv, NULL);
 		localtime_r(&now_tv.tv_sec,&now_tm);
 
@@ -158,20 +214,46 @@
 		fflush(record_f); // flush it from glibc to the kernel.
 		fdatasync(fileno(record_f)); // from buffer cache to disk.
 
-		// eventually wait for full RECORD_TIME
+		// eventually wait for full record_time
 		gettimeofday(&then_tv, NULL);
 		write_duration_us =
 			( (then_tv.tv_sec  - now_tv.tv_sec ) * 1000000 +
 			  (then_tv.tv_usec - now_tv.tv_usec) );
 
+		if(write_duration_us < monitor_time) {
+			if(write_duration_us < min_wd) min_wd = write_duration_us;
+			if(write_duration_us > max_wd) max_wd = write_duration_us;
+
+			avg_write_duration = 
+				(avg_write_duration * avg_wd_nr + 
+				 write_duration_us) / (++avg_wd_nr);
+		}
+
 		pthread_mutex_lock(&data.mutex);
 		data.record_nr = record_nr;
 		data.write_duration_us += write_duration_us;
 		data.write_duration_records++;
+		data.avg_write_duration = avg_write_duration;
 		pthread_mutex_unlock(&data.mutex);
 
-		if(write_duration_us < RECORD_TIME ) {
-			usleep(RECORD_TIME - write_duration_us);
+		if(write_duration_us < record_time ) {
+			usleep(record_time - write_duration_us);
 		}
 	}
+
+	pthread_mutex_lock(&data.mutex);
+	data.record_nr = record_nr;
+	pthread_mutex_unlock(&data.mutex);
+
+	pthread_join(watch_dog,NULL);
+
+	printf( "STATS:\n"
+		"  Records written: %lu\n"
+		"  Average write duration: %.2fms\n"
+		"  Longest write duration (<%dms): %.2fms\n"
+		"  Shortest write duration: %.2fms\n",
+		records,
+		avg_write_duration/1000,
+		monitor_time/1000,(double)max_wd/1000,
+		(double)min_wd/1000);
 }



More information about the drbd-cvs mailing list