[netperf-dev] netperf2 commit notice r126 - in trunk: . src

raj at netperf.org raj at netperf.org
Fri Jun 8 16:43:44 PDT 2007


Author: raj
Date: 2007-06-08 16:43:41 -0700 (Fri, 08 Jun 2007)
New Revision: 126

Modified:
   trunk/Release_Notes
   trunk/src/netlib.c
   trunk/src/netlib.h
   trunk/src/netsh.c
   trunk/src/nettest_bsd.c
Log:
enable bitrate reporting for TCP_RR and add latency et al calcs to verbose output for same

Modified: trunk/Release_Notes
===================================================================
--- trunk/Release_Notes	2007-06-05 21:26:16 UTC (rev 125)
+++ trunk/Release_Notes	2007-06-08 23:43:41 UTC (rev 126)
@@ -2,6 +2,30 @@
 
 Things changed in this release:
 
+*) One can now pass a value of 'x' to the global -f option to specify
+   the units as transactions per second.  This is the default for any
+   request/response test, which is determined by there being a "double
+   `r'" in the name - eg "RR," "rr," "Rr," or "rR."  At present only
+   the TCP_RR test actually looks for this to be set.
+
+*) One can request bits/bytes per second as the primary output of a
+   TCP_RR test by setting the global -f option to [kmgKMG] as with any
+   of the "STREAM" tests.  This converts the primary throughput metric
+   to a bitrate (byterate) following the verbosity rules for a STREAM
+   test.  Service demand remains usec/Transaction regardless of the
+   setting of the global -f option.
+
+   A verbosity level of 2 or more will cause the TCP_RR test to report
+   calculated average RTT latency, transaction rate, and inbound and
+   outbound transfer rates regardless of the primary units selected
+   with the global -f paramter.  If the primary output is transactions
+   per second, the reported inbound and outbound transfer rates will
+   be 10^6 bits per second, otherwise, they honor the setting of the
+   global -f option.
+
+   All of this is EXPERIMENTAL and subject to change without prior
+   notice in future versions of netperf.
+
 *) Replace "break" with "break 2" in acinclude.m4 for a socklen macro
 
 *) The default for the requested socket buffer size is changed from 0
@@ -21,11 +45,11 @@
    version and exit.
 
 *) Setting -I without setting -i will now implicitly set the iteration
-   minimum aand maximums as if a -i 10,3 were set.  Also, some further
+   minimum and maximums as if a -i 10,3 were set.  Also, some further
    sanity checking on the bounds for each is made.
 
 *) Fixed a typo in the manual (found by Emir Halepovic) so the
-   description for the -s and -S options properly speicifies they
+   description for the -s and -S options properly specifies they
    affect the data connection.
 
 These are the Release Notes for Revision 2.4.3 of netperf:

Modified: trunk/src/netlib.c
===================================================================
--- trunk/src/netlib.c	2007-06-05 21:26:16 UTC (rev 125)
+++ trunk/src/netlib.c	2007-06-08 23:43:41 UTC (rev 126)
@@ -244,7 +244,7 @@
 
 FILE    *where;
 
-char    libfmt = 'm';
+char    libfmt = '?';
         
 #ifdef WANT_DLPI
 /* some stuff for DLPI control messages */
@@ -1659,47 +1659,57 @@
 fflush(where);
 }
 
- /***********************************************************************/
- /*                                                                     */
- /*     format_number()                                                 */
- /*                                                                     */
- /* return a pointer to a formatted string containing the value passed  */
- /* translated into the units specified. It assumes that the base units */
- /* are bytes. If the format calls for bits, it will use SI units (10^) */
- /* if the format calls for bytes, it will use CS units (2^)...         */
- /* This routine should look familiar to uses of the latest ttcp...     */
- /*                                                                     */
- /***********************************************************************/
+ /*
 
+      format_number()                                                 
+                                                                    
+  return a pointer to a formatted string containing the value passed
+  translated into the units specified. It assumes that the base units
+  are bytes. If the format calls for bits, it will use SI units (10^)
+  if the format calls for bytes, it will use CS units (2^)...  This
+  routine should look familiar to uses of the latest ttcp...
+
+  we would like to use "t" or "T" for transactions, but probably
+  should leave those for terabits and terabytes respectively, so for
+  transactions, we will use "x" which will, by default, do absolutely
+  nothing to the result.  why?  so we don't have to special case code
+  elsewhere such as in the TCP_RR-as-bidirectional test case.
+
+ */
+ 
+
 char *
 format_number(double number)
 {
-        static  char    fmtbuf[64];
+  static  char    fmtbuf[64];
         
-        switch (libfmt) {
-        case 'K':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f" , number / 1024.0);
-                break;
-        case 'M':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0);
-                break;
-        case 'G':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0 / 1024.0);
-                break;
-        case 'k':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0);
-                break;
-        case 'm':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0);
-                break;
-        case 'g':
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0 / 1000.0);
-                break;
-                default:
-                snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0);
-        }
+  switch (libfmt) {
+  case 'K':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f" , number / 1024.0);
+    break;
+  case 'M':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0);
+    break;
+  case 'G':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0 / 1024.0 / 1024.0);
+    break;
+  case 'k':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0);
+    break;
+  case 'm':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0);
+    break;
+  case 'g':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number * 8 / 1000.0 / 1000.0 / 1000.0);
+    break;
+  case 'x':
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number);
+    break;
+  default:
+    snprintf(fmtbuf, sizeof(fmtbuf),  "%-7.2f", number / 1024.0);
+  }
 
-        return fmtbuf;
+  return fmtbuf;
 }
 
 char
@@ -1782,6 +1792,9 @@
   case 'g':
     strcpy(unitbuf, "10^9bits");
     break;
+  case 'x':
+    strcpy(unitbuf, "Trans");
+    break;
     
   default:
     strcpy(unitbuf, "KBytes");
@@ -2962,6 +2975,7 @@
   
 }
 
+
 double
 calc_thruput_interval(double units_received,double elapsed)
 
@@ -3004,6 +3018,60 @@
   return(calc_thruput_interval(units_received,lib_elapsed));
 }
 
+/* these "_omni" versions are ones which understand 'x' as a unit,
+   meaning transactions/s.  we have a separate routine rather than
+   convert the existing routine so we don't have to go and change
+   _all_ the nettest_foo.c files at one time.  raj 2007-06-08 */
+
+double
+calc_thruput_interval_omni(double units_received,double elapsed)
+
+{
+  double        divisor;
+
+  /* We will calculate the thruput in libfmt units/second */
+  switch (libfmt) {
+  case 'K':
+    divisor = 1024.0;
+    break;
+  case 'M':
+    divisor = 1024.0 * 1024.0;
+    break;
+  case 'G':
+    divisor = 1024.0 * 1024.0 * 1024.0;
+    break;
+  case 'k':
+    divisor = 1000.0 / 8.0;
+    break;
+  case 'm':
+    divisor = 1000.0 * 1000.0 / 8.0;
+    break;
+  case 'g':
+    divisor = 1000.0 * 1000.0 * 1000.0 / 8.0;
+    break;
+  case 'x':
+    divisor = 1.0;
+    break;
+
+  default:
+    fprintf(where,
+	    "WARNING calc_throughput_internal_omni: unknown units %c\n",
+	    libfmt);
+    fflush(where);
+    divisor = 1024.0;
+  }
+  
+  return (units_received / divisor / elapsed);
+
+}
+
+double
+calc_thruput_omni(double units_received)
+
+{
+  return(calc_thruput_interval_omni(units_received,lib_elapsed));
+}
+
 
 
 
@@ -3014,14 +3082,15 @@
   return(calc_cpu_util_internal(elapsed_time));
 }
 
-float calc_service_demand(double units_sent,
-                          float elapsed_time,
-                          float cpu_utilization,
-                          int num_cpus)
+float 
+calc_service_demand_internal(double unit_divisor,
+			     double units_sent,
+			     float elapsed_time,
+			     float cpu_utilization,
+			     int num_cpus)
 
 {
 
-  double unit_divisor = (float)1024.0;
   double service_demand;
   double thruput;
 
@@ -3081,6 +3150,38 @@
   return (float)service_demand;
 }
 
+float calc_service_demand(double units_sent,
+                          float elapsed_time,
+                          float cpu_utilization,
+                          int num_cpus)
+
+{
+
+  double unit_divisor = (double)1024.0;
+
+  return(calc_service_demand_internal(unit_divisor,
+				      units_sent,
+				      elapsed_time,
+				      cpu_utilization,
+				      num_cpus));
+}
+
+float calc_service_demand_trans(double units_sent,
+				float elapsed_time,
+				float cpu_utilization,
+				int num_cpus)
+
+{
+
+  double unit_divisor = (double)1.0;
+
+  return(calc_service_demand_internal(unit_divisor,
+				      units_sent,
+				      elapsed_time,
+				      cpu_utilization,
+				      num_cpus));
+}
+
 
 
 float

Modified: trunk/src/netlib.h
===================================================================
--- trunk/src/netlib.h	2007-06-05 21:26:16 UTC (rev 125)
+++ trunk/src/netlib.h	2007-06-08 23:43:41 UTC (rev 126)
@@ -498,6 +498,8 @@
 extern  void    libmain();
 extern  double  calc_thruput(double units_received);
 extern  double  calc_thruput_interval(double units_received,double elapsed);
+extern  double  calc_thruput_omni(double units_received);
+extern  double  calc_thruput_interval_omni(double units_received,double elapsed);
 extern  float   calibrate_local_cpu(float local_cpu_rate);
 extern  float   calibrate_remote_cpu();
 extern  void    bind_to_specific_processor(int processor_affinity,int use_cpu_map);
@@ -513,9 +515,13 @@
 #endif  /* WIN32 */
 extern  float   calc_cpu_util(float elapsed_time);
 extern  float	calc_service_demand(double units_sent,
-			  float elapsed_time,
-			  float cpu_utilization,
-			  int num_cpus);
+				    float elapsed_time,
+				    float cpu_utilization,
+				    int num_cpus);
+extern  float	calc_service_demand_trans(double units_sent,
+					  float elapsed_time,
+					  float cpu_utilization,
+					  int num_cpus);
 #if defined(__hpux)
 extern  void    catcher(int, siginfo_t *,void *);
 #else

Modified: trunk/src/netsh.c
===================================================================
--- trunk/src/netsh.c	2007-06-05 21:26:16 UTC (rev 125)
+++ trunk/src/netsh.c	2007-06-08 23:43:41 UTC (rev 126)
@@ -938,6 +938,36 @@
 	scan_sdp_args(argc, argv);
       }
 #endif
+    
+    /* what is our default value for the output units?  if the test
+       name contains "RR" or "rr" or "Rr" or "rR" then the default is
+       'x' for transactions. otherwise it is 'm' for megabits
+       (10^6) */
+
+    if ('?' == libfmt) {
+      /* we use a series of strstr's here because not everyone has
+	 strcasestr and I don't feel like up or downshifting text */
+      if ((strstr(test_name,"RR")) ||
+	  (strstr(test_name,"rr")) ||
+	  (strstr(test_name,"Rr")) ||
+	  (strstr(test_name,"rR"))) {
+	libfmt = 'x';
+      }
+      else {
+	libfmt = 'm';
+      }
+    }
+    else if ('x' == libfmt) {
+      /* now, a format of 'x' makes no sense for anything other than
+	 an RR test. if someone has been silly enough to try to set
+	 that, we will reset it silently to default - namely 'm' */
+      if ((strstr(test_name,"RR") == NULL) &&
+	  (strstr(test_name,"rr") == NULL) &&
+	  (strstr(test_name,"Rr") == NULL) &&
+	  (strstr(test_name,"rR") == NULL)) {
+	libfmt = 'm';
+      }
+    }
 }
 
 

Modified: trunk/src/nettest_bsd.c
===================================================================
--- trunk/src/nettest_bsd.c	2007-06-05 21:26:16 UTC (rev 125)
+++ trunk/src/nettest_bsd.c	2007-06-08 23:43:41 UTC (rev 126)
@@ -142,9 +142,10 @@
 #include "hist.h"
 #endif /* WANT_HISTOGRAM */
 
-#ifdef WANT_FIRST_BURST
+/* make first_burst_size unconditional so we can use it easily enough
+   when calculating transaction latency for the TCP_RR test. raj
+   2007-06-08 */
 int first_burst_size=0;
-#endif /* WANT_FIRST_BURST */
 
 #if defined(HAVE_SENDFILE) && (defined(__linux) || defined(__sun__))
 #include <sys/sendfile.h>
@@ -4903,7 +4904,13 @@
 Socket Size   Request  Resp.   Elapsed  Trans.\n\
 Send   Recv   Size     Size    Time     Rate         \n\
 bytes  Bytes  bytes    bytes   secs.    per sec   \n\n";
-  
+
+  char *tput_title_band = "\
+Local /Remote\n\
+Socket Size   Request  Resp.   Elapsed  \n\
+Send   Recv   Size     Size    Time     Throughput \n\
+bytes  Bytes  bytes    bytes   secs.    %s/sec   \n\n";
+
   char *tput_fmt_0 =
     "%7.2f %s\n";
   
@@ -4917,6 +4924,12 @@
 Socket Size   Request Resp.  Elapsed Trans.   CPU    CPU    S.dem   S.dem\n\
 Send   Recv   Size    Size   Time    Rate     local  remote local   remote\n\
 bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
+
+  char *cpu_title_tput = "\
+Local /Remote\n\
+Socket Size   Request Resp.  Elapsed Tput     CPU    CPU    S.dem   S.dem\n\
+Send   Recv   Size    Size   Time    %-8.8s local  remote local   remote\n\
+bytes  bytes  bytes   bytes  secs.   per sec  %% %c    %% %c    us/Tr   us/Tr\n\n";
   
   char *cpu_fmt_0 =
     "%6.3f %c %s\n";
@@ -4928,10 +4941,10 @@
 %-6d %-6d\n";
   
   char *ksink_fmt = "\
-Alignment      Offset\n\
-Local  Remote  Local  Remote\n\
-Send   Recv    Send   Recv\n\
-%5d  %5d   %5d  %5d\n";
+Alignment      Offset         RoundTrip  Trans    Throughput\n\
+Local  Remote  Local  Remote  Latency    Rate     %-8.8s/s\n\
+Send   Recv    Send   Recv    usec/Tran  per sec  Outbound   Inbound\n\
+%5d  %5d   %5d  %5d   %-6.3f   %-6.3f %-6.3f    %-6.3f\n";
   
   
   int			timed_out = 0;
@@ -5405,7 +5418,7 @@
       }
     }
     
-    /* We now calculate what our throughput was for the test. */
+    /* We now calculate what our "throughput" was for the test. */
   
     bytes_xferd	= (req_size * nummessages) + (rsp_size * nummessages);
     thruput	= nummessages/elapsed_time;
@@ -5525,10 +5538,19 @@
     case 1:
     case 2:
       if (print_headers) {
-	fprintf(where,
-		cpu_title,
-		local_cpu_method,
-		remote_cpu_method);
+	if ('x' == libfmt) {
+	  fprintf(where,
+		  cpu_title,
+		  local_cpu_method,
+		  remote_cpu_method);
+	}
+	else {
+	  fprintf(where,
+		  cpu_title_tput,
+		  format_units(),
+		  local_cpu_method,
+		  remote_cpu_method);
+	}	  
       }
 
       fprintf(where,
@@ -5538,7 +5560,9 @@
 	      req_size,		/* how large were the requests */
 	      rsp_size,		/* guess */
 	      elapsed_time,		/* how long was the test */
-	      thruput,
+	      ('x' == libfmt) ? thruput : 
+	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
+					 1.0),
 	      local_cpu_utilization,	/* local cpu */
 	      remote_cpu_utilization,	/* remote cpu */
 	      local_service_demand,	/* local service demand */
@@ -5559,14 +5583,18 @@
     case 0:
       fprintf(where,
 	      tput_fmt_0,
-	      thruput,
+	      ('x' == libfmt) ? thruput :
+	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
+					 1.0),
 	      ((print_headers) || 
 	       (result_brand == NULL)) ? "" : result_brand);
       break;
     case 1:
     case 2:
       if (print_headers) {
-	fprintf(where,tput_title,format_units());
+	fprintf(where,
+		('x' == libfmt) ? tput_title : tput_title_band,
+		format_units());
       }
 
       fprintf(where,
@@ -5576,7 +5604,17 @@
 	      req_size,		/* how large were the requests */
 	      rsp_size,		/* how large were the responses */
 	      elapsed_time, 		/* how long did it take */
-	      thruput,
+	      /* are we trans or do we need to convert to bytes then
+		 bits? at this point, thruput is in our "confident"
+		 transactions per second. we can convert to a
+		 bidirectional bitrate by multiplying that by the sum
+		 of the req_size and rsp_size.  we pass that to
+		 calc_thruput_interval_omni with an elapsed time of
+		 1.0 s to get it converted to [kmg]bits/s or
+		 [KMG]Bytes/s */
+	      ('x' == libfmt) ?  thruput : 
+	      calc_thruput_interval_omni(thruput * (req_size+rsp_size),
+					 1.0),
 	      ((print_headers) || 
 	       (result_brand == NULL)) ? "" : result_brand);
       fprintf(where,
@@ -5601,13 +5639,35 @@
     /* This information will include as much as we can find about */
     /* TCP statistics, the alignments of the sends and receives */
     /* and all that sort of rot... */
-    
+
+    /* normally, you might think that if we were messing about with
+       the value of libfmt we would need to put it back again, but
+       since this is basically the last thing we are going to do with
+       it, it does not matter.  so there :) raj 2007-06-08 */
+    /* if the user was asking for transactions, then we report
+       megabits per sedcond for the unidirectional throughput,
+       otherwise we use the desired units. */
+    if ('x' == libfmt) {
+      libfmt = 'm';
+    }
+
     fprintf(where,
 	    ksink_fmt,
+	    format_units(),
 	    local_send_align,
 	    remote_recv_offset,
 	    local_send_offset,
-	    remote_recv_offset);
+	    remote_recv_offset,
+	    /* if the user has enable burst mode, we have to remember
+	       to account for that in the number of transactions
+	       outstanding at any one time. otherwise we will
+	       underreport the latency of individual
+	       transactions. learned from saf by raj 2007-06-08  */
+	    (((double)1.0/thruput)*(double)1000000.0) * 
+	    (double) (1+first_burst_size),
+	    thruput,
+	    calc_thruput_interval_omni(thruput * (double)req_size,1.0),
+	    calc_thruput_interval_omni(thruput * (double)rsp_size,1.0));
 
 #ifdef WANT_HISTOGRAM
     fprintf(where,"\nHistogram of request/response times\n");



More information about the netperf-dev mailing list