Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/perf/ipc/ping_pong.c

    re131833c rd5caf79  
    2727 */
    2828
    29 #include <math.h>
    3029#include <stdio.h>
    31 #include <stdlib.h>
    32 #include <time.h>
    3330#include <ipc_test.h>
    3431#include <async.h>
    3532#include <errno.h>
     33#include <str_error.h>
     34#include "../benchlist.h"
    3635#include "../perf.h"
    3736
    38 #define MIN_DURATION_SECS  10
    39 #define NUM_SAMPLES 10
     37static ipc_test_t *test = NULL;
    4038
    41 static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter,
    42     uint64_t *rduration)
     39static bool setup(char *error, size_t error_size)
    4340{
    44         struct timespec start;
    45         uint64_t count;
     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        }
    4648
    47         getuptime(&start);
     49        return true;
     50}
    4851
    49         for (count = 0; count < niter; count++) {
    50                 errno_t retval = ipc_test_ping(test);
     52static bool teardown(char *error, size_t error_size)
     53{
     54        ipc_test_destroy(test);
     55        return true;
     56}
    5157
    52                 if (retval != EOK) {
    53                         printf("Error sending ping message.\n");
    54                         return EIO;
     58static 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;
    5571                }
    5672        }
    5773
    58         struct timespec now;
    59         getuptime(&now);
     74        stopwatch_stop(stopwatch);
    6075
    61         *rduration = ts_sub_diff(&now, &start) / 1000;
    62         return EOK;
     76        return true;
    6377}
    6478
    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 }
     79benchmark_t bench_ping_pong = {
     80        .name = "ping_pong",
     81        .desc = "IPC ping-pong benchmark",
     82        .entry = &runner,
     83        .setup = &setup,
     84        .teardown = &teardown
     85};
Note: See TracChangeset for help on using the changeset viewer.