Changeset 3bd74758 in mainline for uspace/app/perf/ipc/ns_ping.c


Ignore:
Timestamp:
2018-12-28T09:32:11Z (7 years ago)
Author:
Vojtech Horky <vojtech.horky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c7de81b
Parents:
8ee106b
Message:

perf: huge refactoring

The overall aim of this refactoring was to remove duplicate code in all
benchmarks that was responsible (a) for computing proper workload size
and (b) for computing final statistics.

After the refactoring, the actual benchmark code is quite short and
takes care of the actual work only.

The harness code was factored out into perf.c that is now responsible
for computing the workload size and then runs the actual benchmark.

As an extra feature, we pass stopwatch_t into the benchmark code that is
only responsible for starting/stopping. Duration is then queried outside
the benchmark code.

File:
1 edited

Legend:

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

    r8ee106b r3bd74758  
    2727 */
    2828
    29 #include <math.h>
    3029#include <stdio.h>
    31 #include <stdlib.h>
    32 #include <time.h>
    3330#include <ns.h>
    3431#include <async.h>
    3532#include <errno.h>
     33#include <str_error.h>
    3634#include "../perf.h"
    3735
    38 #define MIN_DURATION_SECS  10
    39 #define NUM_SAMPLES 10
     36bool bench_ns_ping(stopwatch_t *stopwatch, uint64_t niter,
     37    char *error, size_t error_size)
     38{
     39        stopwatch_start(stopwatch);
    4040
    41 static errno_t ping_pong_measure(uint64_t niter, uint64_t *rduration)
    42 {
    43         struct timespec start;
    44         uint64_t count;
     41        for (uint64_t count = 0; count < niter; count++) {
     42                errno_t rc = ns_ping();
    4543
    46         getuptime(&start);
    47 
    48         for (count = 0; count < niter; count++) {
    49                 errno_t retval = ns_ping();
    50 
    51                 if (retval != EOK) {
    52                         printf("Error sending ping message.\n");
    53                         return EIO;
     44                if (rc != EOK) {
     45                        snprintf(error, error_size,
     46                            "failed sending ping message: %s (%d)",
     47                            str_error(rc), rc);
     48                        return false;
    5449                }
    5550        }
    5651
    57         struct timespec now;
    58         getuptime(&now);
     52        stopwatch_stop(stopwatch);
    5953
    60         *rduration = ts_sub_diff(&now, &start) / 1000;
    61         return EOK;
     54        return true;
    6255}
    63 
    64 static void ping_pong_report(uint64_t niter, uint64_t duration)
    65 {
    66         printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",
    67             niter, duration);
    68 
    69         if (duration > 0) {
    70                 printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);
    71         } else {
    72                 printf(".\n");
    73         }
    74 }
    75 
    76 const char *bench_ns_ping(void)
    77 {
    78         errno_t rc;
    79         uint64_t duration;
    80         uint64_t dsmp[NUM_SAMPLES];
    81 
    82         printf("Warm up and determine work size...\n");
    83 
    84         struct timespec start;
    85         getuptime(&start);
    86 
    87         uint64_t niter = 1;
    88 
    89         while (true) {
    90                 rc = ping_pong_measure(niter, &duration);
    91                 if (rc != EOK)
    92                         return "Failed.";
    93 
    94                 ping_pong_report(niter, duration);
    95 
    96                 if (duration >= MIN_DURATION_SECS * 1000000)
    97                         break;
    98 
    99                 niter *= 2;
    100         }
    101 
    102         printf("Measure %d samples...\n", NUM_SAMPLES);
    103 
    104         int i;
    105 
    106         for (i = 0; i < NUM_SAMPLES; i++) {
    107                 rc = ping_pong_measure(niter, &dsmp[i]);
    108                 if (rc != EOK)
    109                         return "Failed.";
    110 
    111                 ping_pong_report(niter, dsmp[i]);
    112         }
    113 
    114         double sum = 0.0;
    115 
    116         for (i = 0; i < NUM_SAMPLES; i++)
    117                 sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
    118 
    119         double avg = sum / NUM_SAMPLES;
    120 
    121         double qd = 0.0;
    122         double d;
    123         for (i = 0; i < NUM_SAMPLES; i++) {
    124                 d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
    125                 qd += d * d;
    126         }
    127 
    128         double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
    129 
    130         printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",
    131             avg, stddev, NUM_SAMPLES);
    132 
    133         return NULL;
    134 }
Note: See TracChangeset for help on using the changeset viewer.