Add "benchmark" command to work like "benchmark-nl" with echo requests.
authorBen Pfaff <blp@nicira.com>
Tue, 1 Jul 2008 17:50:25 +0000 (10:50 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 1 Jul 2008 17:59:04 +0000 (10:59 -0700)
Suggested by Justin.

utilities/dpctl.8
utilities/dpctl.c

index 018af3b64ce04925e05d1752b8f8d8cb223c86d3..1a714d2ccf0e269521f7e447343aa86e3c5fd5a2 100644 (file)
@@ -146,7 +146,16 @@ tables are removed.  See \fBFLOW SYNTAX\fR, below, for the syntax of
 \fBping \fIswitch \fR[\fIn\fR]
 Sends a series of 10 echo request packets to \fIswitch\fR and times
 each reply.  The echo request packets consist of an OpenFlow header
-plus \fIn\fR bytes (default: 64) of randomly generated payload.
+plus \fIn\fR bytes (default: 64) of randomly generated payload.  This
+measures the latency of individual requests.
+
+.TP
+\fBbenchmark \fIswitch n count\fR
+Sends \fIcount\fR echo request packets that each consist of an
+OpenFlow header plus \fIn\fR bytes of payload and waits for each
+response.  Reports the total time required.  This is a measure of the
+maximum bandwidth to \fIswitch\fR for round-trips of \fIn\fR-byte
+messages.
 
 .SH "FLOW SYNTAX"
 
index e3c70af52ba841ecd3ca0045d4251aa8342354dc..526b1bd891b19a369238e6eb308ea1bc7c638877 100644 (file)
@@ -180,7 +180,8 @@ usage(void)
            "  add-flow SWITCH FLOW        add flow described by FLOW\n"
            "  add-flows SWITCH FILE       add flows from FILE\n"
            "  del-flows SWITCH FLOW       delete matching FLOWs\n"
-           "  ping SWITCH [N]             time N-byte (default: 64) echos\n"
+           "  ping SWITCH [N]             latency of N-byte echos\n"
+           "  benchmark SWITCH N COUNT    bandwidth of COUNT N-byte echos\n"
            "where each SWITCH is an active OpenFlow connection method.\n",
            program_name, program_name);
     vconn_usage(true, false);
@@ -824,7 +825,7 @@ do_ping(int argc, char *argv[])
     struct vconn *vconn;
     int i;
 
-    payload = argc > 2 ? atoi(argv[1]) : 64;
+    payload = argc > 2 ? atoi(argv[2]) : 64;
     if (payload > max_payload) {
         fatal(0, "payload must be between 0 and %zu bytes", max_payload);
     }
@@ -863,6 +864,49 @@ do_ping(int argc, char *argv[])
     vconn_close(vconn);
 }
 
+static void
+do_benchmark(int argc, char *argv[])
+{
+    size_t max_payload = 65535 - sizeof(struct ofp_header);
+    struct timeval start, end;
+    unsigned int payload_size, message_size;
+    struct vconn *vconn;
+    double duration;
+    int count;
+    int i;
+
+    payload_size = atoi(argv[2]);
+    if (payload_size > max_payload) {
+        fatal(0, "payload must be between 0 and %zu bytes", max_payload);
+    }
+    message_size = sizeof(struct ofp_header) + payload_size;
+
+    count = atoi(argv[3]);
+
+    printf("Sending %d packets * %u bytes (with header) = %u bytes total\n",
+           count, message_size, count * message_size);
+
+    run(vconn_open_block(argv[1], &vconn), "connecting to %s", argv[1]);
+    gettimeofday(&start, NULL);
+    for (i = 0; i < count; i++) {
+        struct buffer *request;
+        struct ofp_header *rq_hdr;
+
+        rq_hdr = alloc_openflow_buffer(message_size, OFPT_ECHO_REQUEST,
+                                       &request);
+        memset(rq_hdr + 1, 0, payload_size);
+        buffer_delete(transact_openflow(vconn, request));
+    }
+    gettimeofday(&end, NULL);
+    vconn_close(vconn);
+
+    duration = ((1000*(double)(end.tv_sec - start.tv_sec))
+                + (.001*(end.tv_usec - start.tv_usec)));
+    printf("Finished in %.1f ms (%.0f packets/s) (%.0f bytes/s)\n",
+           duration, count / (duration / 1000.0),
+           count * message_size / (duration / 1000.0));
+}
+
 static void do_help(int argc UNUSED, char *argv[] UNUSED)
 {
     usage();
@@ -889,5 +933,6 @@ static struct command all_commands[] = {
     { "del-flows", 1, 2, do_del_flows },
     { "dump-ports", 1, 1, do_dump_ports },
     { "ping", 1, 2, do_ping },
+    { "benchmark", 3, 3, do_benchmark },
     { NULL, 0, 0, NULL },
 };