From 16ebee832580c2c8744090b9d0d4985ca7d6a069 Mon Sep 17 00:00:00 2001 From: Michal Sojka Date: Mon, 20 Jan 2014 15:09:02 +0100 Subject: [PATCH] Add sendmmsg benchamark --- recvmmsg/bench.sh | 4 +- recvmmsg/can_recvmmsg.c | 88 +++++++++++++++++++++++++--------------- recvmmsg/plot.gp | 49 +++++++++++++++------- recvmmsg/ppc/boot | 3 +- recvmmsg/ppc/mkinitramfs | 21 ---------- 5 files changed, 93 insertions(+), 72 deletions(-) delete mode 100755 recvmmsg/ppc/mkinitramfs diff --git a/recvmmsg/bench.sh b/recvmmsg/bench.sh index faaf8d0..f144167 100755 --- a/recvmmsg/bench.sh +++ b/recvmmsg/bench.sh @@ -1,6 +1,6 @@ #!/bin/sh -echo "Running can_recvmmsg benchmark" +echo >&2 "Running can_recvmmsg benchmark" PATH=../_compiled/bin:$PATH @@ -15,6 +15,6 @@ for i in $COUNTS; do # for j in $(seq 10); do tr=$(can_recvmmsg -q -c $i -r) tm=$(can_recvmmsg -q -c $i -m) - echo $i $tr $tm + printf "%-5d %s\n" $i "$tr $tm" # done done diff --git a/recvmmsg/can_recvmmsg.c b/recvmmsg/can_recvmmsg.c index 4dee5f1..7e21c65 100644 --- a/recvmmsg/can_recvmmsg.c +++ b/recvmmsg/can_recvmmsg.c @@ -16,11 +16,13 @@ #include #include -#define CHECK(cmd) do { if ((cmd) == -1) { perror(#cmd); exit(1); } } while (0) +#define STRINGIFY(val) #val +#define TOSTRING(val) STRINGIFY(val) +#define CHECK(cmd) ({ int ret = (cmd); if (ret == -1) { perror(#cmd " line " TOSTRING(__LINE__)); exit(1); }; ret; }) char *dev = "vcan0"; int count = 10000; -enum { READ, RECVMMSG } recv_method = READ; +enum { READWRITE, MMSG } method = READWRITE; bool quiet = false; /* Subtract the `struct timespec' values X and Y, @@ -29,25 +31,18 @@ bool quiet = false; int timespec_subtract (struct timespec *result, - struct timespec *x, - struct timespec *y) + const struct timespec *x, + const struct timespec *y) { - /* Perform the carry for the later subtraction by updating Y. */ - if (x->tv_nsec < y->tv_nsec) { - int num_sec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1; - y->tv_nsec -= 1000000000 * num_sec; - y->tv_sec += num_sec; - } - if (x->tv_nsec - y->tv_nsec > 1000000000) { - int num_sec = (x->tv_nsec - y->tv_nsec) / 1000000000; - y->tv_nsec += 1000000000 * num_sec; - y->tv_sec -= num_sec; - } + int carry = (x->tv_nsec < y->tv_nsec); + + result->tv_sec = x->tv_sec - y->tv_sec - carry; + result->tv_nsec = x->tv_nsec + carry*1000000000 - y->tv_nsec; - /* Compute the time remaining to wait. - `tv_nsec' is certainly positive. */ - result->tv_sec = x->tv_sec - y->tv_sec; - result->tv_nsec = x->tv_nsec - y->tv_nsec; +/* printf("%ld.%09ld - %ld.%09ld = %ld.%09ld\n", */ +/* x->tv_sec, x->tv_nsec, */ +/* y->tv_sec, y->tv_nsec, */ +/* result->tv_sec, result->tv_nsec); */ /* Return 1 if result is negative. */ return x->tv_sec < y->tv_sec; @@ -61,7 +56,7 @@ void benchmark() struct ifreq ifr; struct can_frame cf; int ret, i; - struct timespec t, t1, t2; + struct timespec ttx, trx, t1, t2; ss = socket(PF_CAN, SOCK_RAW, CAN_RAW); sr = socket(PF_CAN, SOCK_RAW, CAN_RAW); @@ -81,17 +76,43 @@ void benchmark() memset(&cf, 0, sizeof(cf)); cf.can_dlc = 8; - if (!quiet) fprintf(stderr, "Sending %d frames\n", count); - for (i = 0; i < count; i++) { - ret = write(ss, &cf, sizeof(cf)); - if (ret != sizeof(cf)) { - perror("write"); - exit(1); + switch (method) { + case READWRITE: { + if (!quiet) fprintf(stderr, "Sending %d frames via write()\n", count); + clock_gettime(CLOCK_MONOTONIC, &t1); + for (i = 0; i < count; i++) { + ret = write(ss, &cf, sizeof(cf)); + if (ret != sizeof(cf)) { + perror("write"); + exit(1); + } } + clock_gettime(CLOCK_MONOTONIC, &t2); + break; + } + case MMSG: { + if (!quiet) fprintf(stderr, "Sending %d frames via sendmmsg()\n", count); + struct mmsghdr msgs[count]; + struct iovec iovecs[count]; + memset(msgs, 0, sizeof(msgs)); + memset(iovecs, 0, sizeof(iovecs)); + for (i = 0; i < count; i++) { + iovecs[i].iov_base = &cf; + iovecs[i].iov_len = sizeof(cf); + msgs[i].msg_hdr.msg_iov = &iovecs[i]; + msgs[i].msg_hdr.msg_iovlen = 1; + } + clock_gettime(CLOCK_MONOTONIC, &t1); + for (i = 0; i < count; i += ret) + ret = CHECK(sendmmsg(ss, &msgs[i], count - i, 0)); + clock_gettime(CLOCK_MONOTONIC, &t2); + break; + } } + timespec_subtract(&ttx, &t2, &t1); - switch (recv_method) { - case READ: { + switch (method) { + case READWRITE: { if (!quiet) fprintf(stderr, "Receiving %d frames with read()\n", count); clock_gettime(CLOCK_MONOTONIC, &t1); for (i = 0; i < count; i++) { @@ -106,7 +127,7 @@ void benchmark() //fprintf(stderr, "\n"); break; } - case RECVMMSG: { + case MMSG: { if (!quiet) fprintf(stderr, "Receiving %d frames with recvmmsg()\n", count); struct mmsghdr msgs[count]; struct iovec iovecs[count]; @@ -133,8 +154,9 @@ void benchmark() break; } } - timespec_subtract(&t, &t2, &t1); - printf("%d us\n", t.tv_nsec/1000); + timespec_subtract(&trx, &t2, &t1); + printf("tx %ld rx %ld [us]\n", ttx.tv_sec*1000000 + ttx.tv_nsec/1000, + trx.tv_sec*1000000 + trx.tv_nsec/1000); } int main(int argc, char *argv[]) @@ -147,10 +169,10 @@ int main(int argc, char *argv[]) count = atoi(optarg); break; case 'm': - recv_method = RECVMMSG; + method = MMSG; break; case 'r': - recv_method = READ; + method = READWRITE; break; case 'q': quiet = true; diff --git a/recvmmsg/plot.gp b/recvmmsg/plot.gp index 19e18b4..12065f6 100644 --- a/recvmmsg/plot.gp +++ b/recvmmsg/plot.gp @@ -2,26 +2,45 @@ set grid set xlabel "Frames [×1000]" -set ylabel "Time [ms]" +set ylabel "RX Time [ms]" +set y2label "TX Time [ms]" +set y2tics set key left reverse Left -fit a1*x+b1 "data" using 1:2 via a1, b1 -fit a2*x+b2 "data" using 1:4 via a2, b2 +fit ard*x+brd "data" using 1:5 via ard, brd +fit arm*x+brm "data" using 1:10 via arm, brm + +fit awr*x+bwr "data" using 1:3 via awr, bwr +fit asm*x+bsm "data" using 1:8 via asm, bsm set yrange [0:] +set y2range [0:] + +brd=brd/1000 +brm=brm/1000 +bwr=bwr/1000 +bsm=bsm/1000 -b1=b1/1000 -b2=b2/1000 +plot 'data' using ($1/1000):($5/1000) lc 1 title 'read()', \ + 'data' using ($1/1000):($10/1000) lc 1 title 'recvmmsg()', \ + 'data' using ($1/1000):($3/1000) lc 2 axes x1y2 title 'write()', \ + 'data' using ($1/1000):($8/1000) lc 2 axes x1y2 title 'sendmmsg()', \ + ard*x+brd with lines lt 1 lc rgbcolor "#aa0000" lw 1 title "", \ + arm*x+brm with lines lt 2 lc rgbcolor "#aa0000" lw 1 title "", \ + awr*x+bwr with lines axes x1y2 lt 1 lc rgbcolor "#00aa00" lw 1 title "", \ + asm*x+bsm with lines axes x1y2 lt 2 lc rgbcolor "#00aa00" lw 1 title "" -plot 'data' using ($1/1000):($2/1000) title 'read()', \ - 'data' using ($1/1000):($4/1000) title 'recvmmsg()', \ - a1*x+b1 with lines lt 1 lc rgbcolor "#aa0000" lw 5 title "", \ - a2*x+b2 with lines lt 1 lc rgbcolor "#00aa00" lw 5 title "" +# aread*x+bread - arecv*x-brecv = 0 +# (aread-arecv)*x = brecv-bread +xeq = (brm-brd)/(ard-arm) +print "ard = ", ard +print "arm = ", arm +print "arm/ard = ", arm/ard +print "Intersection at x = ", xeq +print "" -# a1*x+b1 - a2*x-b2 = 0 -# (a1-a2)*x = b2-b1 -xeq = (b2-b1)/(a1-a2) -print "ar = ", a1 -print "am = ", a2 -print "ar/am = ", a1/a2 +xeq = (bsm-bwr)/(awr-asm) +print "awr = ", awr +print "asm = ", asm +print "asm/awr = ", asm/awr print "Intersection at x = ", xeq diff --git a/recvmmsg/ppc/boot b/recvmmsg/ppc/boot index 4880855..0188252 100755 --- a/recvmmsg/ppc/boot +++ b/recvmmsg/ppc/boot @@ -3,4 +3,5 @@ EXITON=Welcome to Buildroot load uImage console=ttyPSC0,115200 load shark-ryu.dtb -load rootfs2.uImage < $SRCDIR/mkinitramfs +load rootfsmmsg.uImage < gen_cpio --mkimage="-T ramdisk -A powerpc -O linux" \ + rootfs.cpio "$SRCDIR/../bench.sh->/etc/init.d/S50benchmark" "can_recvmmsg->/bin/" diff --git a/recvmmsg/ppc/mkinitramfs b/recvmmsg/ppc/mkinitramfs deleted file mode 100755 index c6b4f31..0000000 --- a/recvmmsg/ppc/mkinitramfs +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -SRCDIR=${SRCDIR:-$(dirname $0)} - -tmpcpio=$(mktemp) -catcpio=$(mktemp) -uimage=$(mktemp) - -gen_init_cpio - < $tmpcpio -dir /etc 0755 0 0 -dir /etc/init.d 0755 0 0 -file /etc/init.d/S50benchmark $SRCDIR/../bench.sh 0755 0 0 -dir /bin 0755 0 0 -file /bin/can_recvmmsg can_recvmmsg 0755 0 0 -EOF - -cat $SRCDIR/rootfs.cpio $tmpcpio > $catcpio -mkimage -T ramdisk -A powerpc -O linux -d $catcpio $uimage >&2 -cat $uimage - -rm $catcpio $tmpcpio $uimage -- 2.39.2