[openib-general] perftest-06 patch - output routines
Grant Grundler
iod00d at hp.com
Tue May 17 08:51:50 PDT 2005
Michael,
The basic measurement is in integer (cycles_t) units.
I don't like to convert to floating point until we have to.
The following patch makes delta[] an array of cycles_t
and doesn't convert to floating point until the values
are printed as microseconds.
This patch completely restructures the output:
o replace report-all with report-histogram.
If someone really want's "all", use -UH (or add an alias "-A").
Normal use case is someone just wants one or the other.
"-H" is soft-of-shorthand for "rdma_lat | sort -k2 -n"
o shortened the summary to 1 line of output (min/median/max)
o print_mhz() and print_cycles() are seperate...a bit more
twiddling and they could be unified again.
But it's pretty clear what's going on and merging
them back together again makes it less clear.
o some additional white space cleanups.
thanks,
grant
Index: perftest/rdma_lat.c
===================================================================
--- perftest/rdma_lat.c (revision 2359)
+++ perftest/rdma_lat.c (working copy)
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2005 Topspin Communications. All rights reserved.
* Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
+ * Copyright (c) 2005 Hewlett Packard, Inc (Grant Grundler)
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
@@ -57,22 +58,14 @@
#include "get_clock.h"
-static int double_compar(const void * aptr, const void * bptr)
-{
- const double *a = aptr;
- const double *b = bptr;
-
- if (*a < *b) return -1;
- if (*a > *b) return 1;
- else return 0;
-}
-
-enum {
- PINGPONG_RDMA_WRID = 3,
-};
+#define PINGPONG_RDMA_WRID 3
static int page_size;
+static int report_unsorted;
+static int report_histogram;
+static int report_cycles; /* report delta's in cycles, not microsec's */
+
struct pingpong_context {
struct ibv_context *context;
@@ -462,6 +455,107 @@ static void usage(const char *argv0)
printf(" -U, --report-unsorted (implies -A) print out unsorted results (default sorted)\n");
}
+static inline cycles_t get_median(int iters, cycles_t delta[])
+{
+ /*
+ * When there is an
+ * odd number of samples, the median is the middle number.
+ * even number of samples, the median is the mean of the
+ * two middle numbers.
+ *
+ * Reminder: iters is the number of exchanges, not number of samples.
+ */
+ if ((iters - 1) & 1)
+ return delta[iters / 2];
+ else
+ return (delta[iters / 2] + delta[iters / 2 - 1]) / 2;
+}
+
+static int cycles_cmp(const void * aptr, const void * bptr)
+{
+ const cycles_t *a = aptr;
+ const cycles_t *b = bptr;
+ if (*a < *b) return -1;
+ if (*a > *b) return 1;
+ return 0;
+}
+
+#define dump_delta(h, f, d, iters, delta) \
+{ \
+ unsigned int i; \
+ printf("#, usec\n"); \
+ for(i = 0; i < (iters)-1; ++i) \
+ printf(f, i+1, delta[i] / (d)); \
+ printf("\n\n"); \
+}
+
+static void print_hz(unsigned int iters, cycles_t *tstamp)
+{
+ double mhz = 2 * get_cpu_mhz();
+ cycles_t median;
+ cycles_t *delta = malloc(iters * sizeof *delta);
+ unsigned int i;
+
+ if (!delta) {
+ perror("malloc");
+ exit (0);
+ }
+
+ for (i = 0; i < iters; ++i)
+ delta[i] = tstamp[i + 1] - tstamp[i];
+
+ if (report_unsorted)
+ dump_delta("#, usec\n", "%d, %f\n", mhz, iters, delta);
+
+ qsort(delta, iters - 1, sizeof *delta, cycles_cmp);
+
+ if (report_histogram)
+ dump_delta("#, usec\n", "%d, %f\n", mhz, iters, delta);
+
+ median = get_median(iters, delta);
+
+ printf("Latency min/median/max: %f/%f/%f\n",
+ delta[0]/mhz, median/mhz, delta[iters-2]/mhz);
+
+ free(delta);
+}
+
+
+static void print_cycles(unsigned int iters, cycles_t *tstamp)
+{
+ cycles_t median;
+ cycles_t *delta = malloc(iters * sizeof *delta);
+ unsigned int i;
+
+ if (!delta) {
+ perror("malloc");
+ exit (0);
+ }
+
+ for (i = 0; i < iters ; ++i)
+ delta[i] = tstamp[i + 1] - tstamp[i];
+
+ if (report_unsorted)
+ dump_delta("#, cycles\n", "%d, %lu\n", 2, iters, delta);
+
+ qsort(delta, (iters - 1), sizeof *delta, cycles_cmp);
+
+ /* Definition of histogram:
+ * http://www.itl.nist.gov/div898/handbook/eda/section3/histogra.htm
+ */
+ if (report_histogram)
+ dump_delta("#, cycles\n", "%d, %lu\n", 2, iters, delta);
+
+ median = get_median(iters, delta);
+
+ printf("Latency min/median/max: %lu/%lu/%lu cycles\n",
+ (unsigned long) delta[0]/2,
+ (unsigned long) median/2,
+ (unsigned long) delta[iters-2]/2);
+
+ free(delta);
+}
+
int main(int argc, char *argv[])
{
struct dlist *dev_list;
@@ -477,9 +571,6 @@ int main(int argc, char *argv[])
int rx_depth = 1;
int tx_depth = 50;
int iters = 1000;
- int report_all = 0;
- int report_unsorted = 0;
- int report_cpu_cycles = 0;
int scnt, rcnt, ccnt;
int client_first_post;
int sockfd;
@@ -489,12 +580,6 @@ int main(int argc, char *argv[])
volatile char *post_buf;
cycles_t *tstamp;
- double median;
- double *delta;
- int i;
-
- double mhz;
- const char* units;
/* Parameter parsing. */
while (1) {
@@ -508,12 +593,12 @@ int main(int argc, char *argv[])
{ .name = "iters", .has_arg = 1, .val = 'n' },
{ .name = "tx-depth", .has_arg = 1, .val = 't' },
{ .name = "report-cycles", .has_arg = 0, .val = 'C' },
- { .name = "report-all", .has_arg = 0, .val = 'A' },
+ { .name = "report-histogram", .has_arg = 0, .val = 'H' },
{ .name = "report-unsorted",.has_arg = 0, .val = 'U' },
{ 0 }
};
- c = getopt_long(argc, argv, "p:d:i:s:n:t:CAU", long_options, NULL);
+ c = getopt_long(argc, argv, "p:d:i:s:n:t:CHU", long_options, NULL);
if (c == -1)
break;
@@ -555,17 +640,16 @@ int main(int argc, char *argv[])
break;
- case 'A':
- report_all = 1;
+ case 'C':
+ report_cycles = 1;
break;
- case 'C':
- report_cpu_cycles = 1;
+ case 'H':
+ report_histogram = 1;
break;
case 'U':
report_unsorted = 1;
- report_all = 1;
break;
default:
@@ -586,14 +670,6 @@ int main(int argc, char *argv[])
srand48(getpid() * time(NULL));
- if (report_cpu_cycles) {
- mhz = 1;
- units = "usec";
- } else {
- mhz = get_cpu_mhz();
- units = "clocks";
- }
-
page_size = sysconf(_SC_PAGESIZE);
dev_list = ibv_get_devices();
@@ -640,15 +716,13 @@ int main(int argc, char *argv[])
if (servername) {
sockfd = pp_client_connect(servername, port);
- } else {
- sockfd = pp_server_connect(port);
- }
- if (sockfd < 0)
- return 1;
-
- if (servername) {
+ if (sockfd < 0)
+ return 1;
rem_dest = pp_client_exch_dest(sockfd, &my_dest);
} else {
+ sockfd = pp_server_connect(port);
+ if (sockfd < 0)
+ return 1;
rem_dest = pp_server_exch_dest(sockfd, &my_dest);
}
@@ -751,54 +825,11 @@ int main(int argc, char *argv[])
}
}
- /* Done with the test. Report results. */
-
- delta = malloc(iters * sizeof *delta);
- if (!delta) {
- perror("malloc");
- return 1;
- }
-
- for (i = 0; i < iters - 1; ++i) {
- delta[i]=(tstamp[i + 1] - tstamp[i]) / mhz;
- }
-
- if (report_unsorted) {
- printf("#, %s\n", units);
- for(i = 0; i < iters - 1; ++i) {
- printf("%d, %f\n", i, delta[i] / 2);
- }
-
- printf("\n\n");
- }
-
- qsort(delta, iters - 1, sizeof *delta, double_compar);
-
- if (report_all && ! report_unsorted) {
- printf("#, %s\n", units);
- for(i = 0; i < iters - 1; ++i) {
- printf("%d, %f\n", i, delta[i] / 2);
- }
-
- printf("\n\n");
- }
-
- /* When there is an odd number of numbers, the median is simply
- * the middle number.
- * When there is an even number of numbers, the median is the mean
- * of the two middle numbers.
- *
- * Reminder: iters is the number of exchanges, not number of samples.
- */
-
- if ((iters - 1) % 2)
- median = delta[iters / 2];
- else
- median = (delta[iters / 2] + delta[iters / 2 + 1]) / 2;
-
- printf("Latency minimum: %f %s\n", delta[0] / 2, units);
- printf("Latency statistical median: %f %s\n", median / 2, units);
- printf("Latency maximum: %f %s\n", delta[iters - 2] / 2, units);
+ if (report_cycles)
+ print_cycles(iters, tstamp);
+ else
+ print_hz(iters, tstamp);
+ free(tstamp);
return 0;
}
More information about the general
mailing list