Changes in uspace/app/perf/ipc/ping_pong.c [d5caf79:e131833c] in mainline
- File:
-
- 1 edited
-
uspace/app/perf/ipc/ping_pong.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/perf/ipc/ping_pong.c
rd5caf79 re131833c 27 27 */ 28 28 29 #include <math.h> 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <time.h> 30 33 #include <ipc_test.h> 31 34 #include <async.h> 32 35 #include <errno.h> 33 #include <str_error.h>34 #include "../benchlist.h"35 36 #include "../perf.h" 36 37 37 static ipc_test_t *test = NULL; 38 #define MIN_DURATION_SECS 10 39 #define NUM_SAMPLES 10 38 40 39 static bool setup(char *error, size_t error_size) 41 static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter, 42 uint64_t *rduration) 40 43 { 41 errno_t rc = ipc_test_create(&test); 42 if (rc != EOK) { 43 snprintf(error, error_size, 44 "failed contacting IPC test server: %s (%d)", 45 str_error(rc), rc); 46 return false; 47 } 44 struct timespec start; 45 uint64_t count; 48 46 49 return true; 50 } 47 getuptime(&start); 51 48 52 static bool teardown(char *error, size_t error_size) 53 { 54 ipc_test_destroy(test); 55 return true; 56 } 49 for (count = 0; count < niter; count++) { 50 errno_t retval = ipc_test_ping(test); 57 51 58 static bool runner(stopwatch_t *stopwatch, uint64_t niter, 59 char *error, size_t error_size) 60 { 61 stopwatch_start(stopwatch); 62 63 for (uint64_t count = 0; count < niter; count++) { 64 errno_t rc = ipc_test_ping(test); 65 66 if (rc != EOK) { 67 snprintf(error, error_size, 68 "failed sending ping message: %s (%d)", 69 str_error(rc), rc); 70 return false; 52 if (retval != EOK) { 53 printf("Error sending ping message.\n"); 54 return EIO; 71 55 } 72 56 } 73 57 74 stopwatch_stop(stopwatch); 58 struct timespec now; 59 getuptime(&now); 75 60 76 return true; 61 *rduration = ts_sub_diff(&now, &start) / 1000; 62 return EOK; 77 63 } 78 64 79 benchmark_t bench_ping_pong = { 80 .name = "ping_pong", 81 .desc = "IPC ping-pong benchmark", 82 .entry = &runner, 83 .setup = &setup, 84 .teardown = &teardown 85 }; 65 static void ping_pong_report(uint64_t niter, uint64_t duration) 66 { 67 printf("Completed %" PRIu64 " round trips in %" PRIu64 " us", 68 niter, duration); 69 70 if (duration > 0) { 71 printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration); 72 } else { 73 printf(".\n"); 74 } 75 } 76 77 const char *bench_ping_pong(void) 78 { 79 errno_t rc; 80 uint64_t duration; 81 uint64_t dsmp[NUM_SAMPLES]; 82 ipc_test_t *test; 83 const char *msg; 84 85 rc = ipc_test_create(&test); 86 if (rc != EOK) 87 return "Failed contacting IPC test server."; 88 89 printf("Warm up and determine work size...\n"); 90 91 struct timespec start; 92 getuptime(&start); 93 94 uint64_t niter = 1; 95 96 while (true) { 97 rc = ping_pong_measure(test, niter, &duration); 98 if (rc != EOK) { 99 msg = "Failed."; 100 goto error; 101 } 102 103 ping_pong_report(niter, duration); 104 105 if (duration >= MIN_DURATION_SECS * 1000000) 106 break; 107 108 niter *= 2; 109 } 110 111 printf("Measure %d samples...\n", NUM_SAMPLES); 112 113 int i; 114 115 for (i = 0; i < NUM_SAMPLES; i++) { 116 rc = ping_pong_measure(test, niter, &dsmp[i]); 117 if (rc != EOK) { 118 msg = "Failed."; 119 goto error; 120 } 121 122 ping_pong_report(niter, dsmp[i]); 123 } 124 125 double sum = 0.0; 126 127 for (i = 0; i < NUM_SAMPLES; i++) 128 sum += (double)niter / ((double)dsmp[i] / 1000000.0l); 129 130 double avg = sum / NUM_SAMPLES; 131 132 double qd = 0.0; 133 double d; 134 for (i = 0; i < NUM_SAMPLES; i++) { 135 d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg; 136 qd += d * d; 137 } 138 139 double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt 140 141 printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n", 142 avg, stddev, NUM_SAMPLES); 143 144 ipc_test_destroy(test); 145 return NULL; 146 error: 147 ipc_test_destroy(test); 148 return msg; 149 }
Note:
See TracChangeset
for help on using the changeset viewer.
