[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