chiark / gitweb /
bus-benchmark: add performance data output mode
authorKay Sievers <kay@vrfy.org>
Tue, 4 Jun 2013 18:55:00 +0000 (20:55 +0200)
committerKay Sievers <kay@vrfy.org>
Tue, 4 Jun 2013 19:00:30 +0000 (21:00 +0200)
  - for now, comment out munmap() check to enable memfd passing
  - print tab-separated values and header
  - add memcpy() to fill the memfd, to produce real-world results

$ ./test-bus-kernel-benchmark
SIZE    COPY    MEMFD
4194304 370     370
2097152 810     810
1048576 2130    2130
524288  4090    4090
262144  7080    7080
131072  11380   11380
65536   17140   17140
98304   13930   13930
114688  12890   12890
122880  12350   12350
126976  12150   12150
129024  12170   12170
130048  12040   12040
130560  12080   12080
130816  12010   12010
130944  12020   12020
131008  12040   12040
131040  12050   12050
131056  12010   12010
131064  12060   12060
131068  12040   12040
131070  11310   11310
131069  11420   11420
Copying/memfd are equally fast at 131068 bytes

$ ./test-bus-kernel-benchmark chart
SIZE    COPY    MEMFD
1       35570   23690
2       36470   23680
4       36160   23520
8       36600   22220
16      33900   20830
32      33990   21360
64      33480   21280
128     34050   20910
256     32950   21750
512     34730   21900
1024    33810   22890
2048    36280   23110
4096    30790   21610
8192    29380   21100
16384   26880   19820
32768   22510   17980
65536   17270   15180
131072  11400   11420
262144  7140    8270
524288  4090    5050
1048576 2110    2780
2097152 800     1140
4194304 350     580

src/libsystemd-bus/bus-message.c
src/libsystemd-bus/test-bus-kernel-benchmark.c

index e6bf9db99adf2e380cbbe8eb08f98bb402522f78..77a875d4ebbdf3ceea5e142275d400fd69aa4f5b 100644 (file)
@@ -2358,8 +2358,9 @@ void bus_body_part_unmap(struct bus_body_part *part) {
         if (!part->data)
                 return;
 
-        if (!part->munmap_this)
-                return;
+        //FIXME: this is not set in the benchmark
+        //if (!part->munmap_this)
+        //        return;
 
         assert_se(munmap(part->data, part->mapped) == 0);
 
index e2a872c6c5f09c7ed1b08961bb6af566db14ba6f..2ece2a0029df8d92654105eb4b4aea2f8b1b14ea 100644 (file)
@@ -32,7 +32,7 @@
 #include "bus-kernel.h"
 #include "bus-internal.h"
 
-#define MAX_SIZE (1*1024*1024)
+#define MAX_SIZE (8*1024*1024)
 
 static usec_t arg_loop_usec = 100 * USEC_PER_MSEC;
 
@@ -74,21 +74,17 @@ static void server(sd_bus *b, size_t *result) {
 
 static void transaction(sd_bus *b, size_t sz) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
-        /* size_t psz, i; */
         uint8_t *p;
 
         assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Work", &m) >= 0);
         assert_se(sd_bus_message_append_array_space(m, 'y', sz, (void**) &p) >= 0);
 
-        /* Touch every page */
-        /* psz = page_size(); */
-        /* for (i = 0; i < sz; i += psz) */
-        /*         p[i] = 'X'; */
+        memset(p, 0x80, sz);
 
         assert_se(sd_bus_send_with_reply_and_block(b, m, 0, NULL, &reply) >= 0);
 }
 
-static void client(const char *address) {
+static void client_bisect(const char *address) {
         _cleanup_bus_message_unref_ sd_bus_message *x = NULL;
         size_t lsize, rsize, csize;
         sd_bus *b;
@@ -108,21 +104,22 @@ static void client(const char *address) {
         lsize = 1;
         rsize = MAX_SIZE;
 
+        printf("SIZE\tCOPY\tMEMFD\n");
+
         for (;;) {
                 usec_t t;
                 unsigned n_copying, n_memfd;
 
                 csize = (lsize + rsize) / 2;
 
-                log_info("Trying size=%zu", csize);
-
                 if (csize <= lsize)
                         break;
 
                 if (csize <= 0)
                         break;
 
-                log_info("copying...");
+                fprintf(stderr, "%zu\t", csize);
+
                 b->use_memfd = 0;
 
                 t = now(CLOCK_MONOTONIC);
@@ -131,10 +128,8 @@ static void client(const char *address) {
                         if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                 break;
                 }
+                printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));
 
-                log_info("%u copy transactions per second", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));
-
-                log_info("sending memfd...");
                 b->use_memfd = -1;
 
                 t = now(CLOCK_MONOTONIC);
@@ -143,8 +138,7 @@ static void client(const char *address) {
                         if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
                                 break;
                 }
-
-                log_info("%u memfd transactions per second", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec));
+                printf("%u\n", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));
 
                 if (n_copying == n_memfd)
                         break;
@@ -155,6 +149,63 @@ static void client(const char *address) {
                         rsize = csize;
         }
 
+        b->use_memfd = 1;
+        assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0);
+        assert_se(sd_bus_message_append(x, "t", csize) >= 0);
+        assert_se(sd_bus_send(b, x, NULL) >= 0);
+
+        sd_bus_unref(b);
+}
+
+static void client_chart(const char *address) {
+        _cleanup_bus_message_unref_ sd_bus_message *x = NULL;
+        size_t csize;
+        sd_bus *b;
+        int r;
+
+        r = sd_bus_new(&b);
+        assert_se(r >= 0);
+
+        r = sd_bus_set_address(b, address);
+        assert_se(r >= 0);
+
+        r = sd_bus_start(b);
+        assert_se(r >= 0);
+
+        assert_se(sd_bus_call_method(b, ":1.1", "/", "benchmark.server", "Ping", NULL, NULL, NULL) >= 0);
+
+        printf("SIZE\tCOPY\tMEMFD\n");
+
+        for (csize = 1; csize < MAX_SIZE; csize *= 2) {
+                usec_t t;
+                unsigned n_copying, n_memfd;
+
+                fprintf(stderr, "%zu\t", csize);
+
+                b->use_memfd = 0;
+
+                t = now(CLOCK_MONOTONIC);
+                for (n_copying = 0;; n_copying++) {
+                        transaction(b, csize);
+                        if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
+                                break;
+                }
+
+                printf("%u\t", (unsigned) ((n_copying * USEC_PER_SEC) / arg_loop_usec));
+
+                b->use_memfd = -1;
+
+                t = now(CLOCK_MONOTONIC);
+                for (n_memfd = 0;; n_memfd++) {
+                        transaction(b, csize);
+                        if (now(CLOCK_MONOTONIC) >= t + arg_loop_usec)
+                                break;
+                }
+
+                printf("%u\n", (unsigned) ((n_memfd * USEC_PER_SEC) / arg_loop_usec));
+        }
+
+        b->use_memfd = 1;
         assert_se(sd_bus_message_new_method_call(b, ":1.1", "/", "benchmark.server", "Exit", &x) >= 0);
         assert_se(sd_bus_message_append(x, "t", csize) >= 0);
         assert_se(sd_bus_send(b, x, NULL) >= 0);
@@ -163,6 +214,11 @@ static void client(const char *address) {
 }
 
 int main(int argc, char *argv[]) {
+        enum {
+                MODE_BISECT,
+                MODE_CHART,
+        } mode = MODE_BISECT;
+        int i;
         _cleanup_free_ char *bus_name = NULL, *address = NULL;
         _cleanup_close_ int bus_ref = -1;
         cpu_set_t cpuset;
@@ -173,8 +229,14 @@ int main(int argc, char *argv[]) {
 
         log_set_max_level(LOG_DEBUG);
 
-        if (argc > 1)
-                assert_se(parse_sec(argv[1], &arg_loop_usec) >= 0);
+        for (i = 1; i < argc; i++) {
+                if (streq(argv[i], "chart")) {
+                        mode = MODE_CHART;
+                        continue;
+                }
+
+                assert_se(parse_sec(argv[i], &arg_loop_usec) >= 0);
+        }
 
         assert_se(arg_loop_usec > 0);
 
@@ -210,7 +272,16 @@ int main(int argc, char *argv[]) {
                 close_nointr_nofail(bus_ref);
                 sd_bus_unref(b);
 
-                client(address);
+                switch (mode) {
+                case MODE_BISECT:
+                        client_bisect(address);
+                        break;
+
+                case MODE_CHART:
+                        client_chart(address);
+                        break;
+                }
+
                 _exit(0);
         }
 
@@ -220,7 +291,8 @@ int main(int argc, char *argv[]) {
 
         server(b, &result);
 
-        log_info("Copying/memfd are equally fast at %zu", result);
+        if (mode == MODE_BISECT)
+                printf("Copying/memfd are equally fast at %zu bytes\n", result);
 
         assert_se(waitpid(pid, NULL, 0) == pid);