Changeset d6d6b3e in mainline for uspace/app/tester/ipc/ping_pong.c


Ignore:
Timestamp:
2018-11-02T10:35:43Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e131bd05
Parents:
2e4343b
git-author:
Jiri Svoboda <jiri@…> (2018-11-01 22:34:53)
git-committer:
Jiri Svoboda <jiri@…> (2018-11-02 10:35:43)
Message:

IPC benchmark can be more precise and more scientific.

File:
1 edited

Legend:

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

    r2e4343b rd6d6b3e  
    2727 */
    2828
     29#include <math.h>
    2930#include <stdio.h>
    3031#include <stdlib.h>
     
    3536#include "../tester.h"
    3637
    37 #define DURATION_SECS      10
    38 #define COUNT_GRANULARITY  100
     38#define MIN_DURATION_SECS  10
     39#define NUM_SAMPLES 10
     40
     41static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
     42{
     43        struct timespec start;
     44        uint64_t count;
     45
     46        getuptime(&start);
     47
     48        for (count = 0; count < niter; count++) {
     49                errno_t retval = ns_ping();
     50
     51                if (retval != EOK) {
     52                        TPRINTF("Error sending ping message.\n");
     53                        return EIO;
     54                }
     55        }
     56
     57        struct timespec now;
     58        getuptime(&now);
     59
     60        *rduration = ts_sub_diff(&now, &start) / 1000;
     61        return EOK;
     62}
     63
     64static void ping_pong_report(uint64_t niter, uint64_t duration)
     65{
     66        TPRINTF("Completed %" PRIu64 " round trips in %" PRIu64" us",
     67            niter, duration);
     68
     69        if (duration > 0) {
     70                TPRINTF(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
     71        } else {
     72                TPRINTF(".\n");
     73        }
     74}
    3975
    4076const char *test_ping_pong(void)
    4177{
    42         TPRINTF("Pinging ns server for %d seconds...", DURATION_SECS);
     78        errno_t rc;
     79        uint64_t duration;
     80        uint64_t dsmp[NUM_SAMPLES];
     81
     82        TPRINTF("Benchmark ns server ping time\n");
     83        TPRINTF("Warm up and determine work size...\n");
    4384
    4485        struct timespec start;
    4586        getuptime(&start);
    4687
    47         uint64_t count = 0;
     88        uint64_t niter = 1;
     89
    4890        while (true) {
    49                 struct timespec now;
    50                 getuptime(&now);
     91                rc = ping_pong_measure(niter, &duration);
     92                if (rc != EOK)
     93                        return "Failed.";
    5194
    52                 if (NSEC2SEC(ts_sub_diff(&now, &start)) >= DURATION_SECS)
     95                ping_pong_report(niter, duration);
     96
     97                if (duration >= MIN_DURATION_SECS * 1000000)
    5398                        break;
    5499
    55                 size_t i;
    56                 for (i = 0; i < COUNT_GRANULARITY; i++) {
    57                         errno_t retval = ns_ping();
    58 
    59                         if (retval != EOK) {
    60                                 TPRINTF("\n");
    61                                 return "Failed to send ping message";
    62                         }
    63                 }
    64 
    65                 count += COUNT_GRANULARITY;
     100                niter *= 2;
    66101        }
    67102
    68         TPRINTF("OK\nCompleted %" PRIu64 " round trips in %u seconds, %" PRIu64 " rt/s.\n",
    69             count, DURATION_SECS, count / DURATION_SECS);
     103        TPRINTF("Measure %d samples...\n", NUM_SAMPLES);
     104
     105        int i;
     106
     107        for (i = 0; i < NUM_SAMPLES; i++) {
     108                rc = ping_pong_measure(niter, &dsmp[i]);
     109                if (rc != EOK)
     110                        return "Failed.";
     111
     112                ping_pong_report(niter, dsmp[i]);
     113        }
     114
     115        double sum = 0.0;
     116
     117        for (i = 0; i < NUM_SAMPLES; i++)
     118                sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
     119
     120        double avg = sum / NUM_SAMPLES;
     121
     122        double qd = 0.0;
     123        double d;
     124        for (i = 0; i < NUM_SAMPLES; i++) {
     125                d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
     126                qd += d*d;
     127        }
     128
     129        double stddev = qd; // XXX sqrt
     130
     131        TPRINTF("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
     132            avg, stddev, NUM_SAMPLES);
    70133
    71134        return NULL;
Note: See TracChangeset for help on using the changeset viewer.