Changeset 3bd74758 in mainline for uspace/app/perf/malloc/malloc1.c


Ignore:
Timestamp:
2018-12-28T09:32:11Z (5 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/malloc/malloc1.c

    r8ee106b r3bd74758  
    3030#include <stdio.h>
    3131#include <stdlib.h>
    32 #include <time.h>
    33 #include <errno.h>
    3432#include "../perf.h"
    3533
    36 #define MIN_DURATION_SECS  10
    37 #define NUM_SAMPLES 10
    38 
    39 static errno_t malloc1_measure(uint64_t niter, uint64_t *rduration)
     34bool bench_malloc1(stopwatch_t *stopwatch, uint64_t size,
     35    char *error, size_t error_size)
    4036{
    41         struct timespec start;
    42         uint64_t count;
    43         void *p;
    44 
    45         getuptime(&start);
    46 
    47         for (count = 0; count < niter; count++) {
    48                 p = malloc(1);
    49                 if (p == NULL)
    50                         return ENOMEM;
     37        stopwatch_start(stopwatch);
     38        for (uint64_t i = 0; i < size; i++) {
     39                void *p = malloc(1);
     40                if (p == NULL) {
     41                        snprintf(error, error_size,
     42                            "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
     43                            i, size);
     44                        return false;
     45                }
    5146                free(p);
    5247        }
     48        stopwatch_stop(stopwatch);
    5349
    54         struct timespec now;
    55         getuptime(&now);
    56 
    57         *rduration = ts_sub_diff(&now, &start) / 1000;
    58         return EOK;
     50        return true;
    5951}
    60 
    61 static void malloc1_report(uint64_t niter, uint64_t duration)
    62 {
    63         printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",
    64             niter, duration);
    65 
    66         if (duration > 0) {
    67                 printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);
    68         } else {
    69                 printf(".\n");
    70         }
    71 }
    72 
    73 const char *bench_malloc1(void)
    74 {
    75         errno_t rc;
    76         uint64_t duration;
    77         uint64_t dsmp[NUM_SAMPLES];
    78         const char *msg;
    79 
    80         printf("Warm up and determine work size...\n");
    81 
    82         struct timespec start;
    83         getuptime(&start);
    84 
    85         uint64_t niter = 1;
    86 
    87         while (true) {
    88                 rc = malloc1_measure(niter, &duration);
    89                 if (rc != EOK) {
    90                         msg = "Failed.";
    91                         goto error;
    92                 }
    93 
    94                 malloc1_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 = malloc1_measure(niter, &dsmp[i]);
    108                 if (rc != EOK) {
    109                         msg = "Failed.";
    110                         goto error;
    111                 }
    112 
    113                 malloc1_report(niter, dsmp[i]);
    114         }
    115 
    116         double sum = 0.0;
    117 
    118         for (i = 0; i < NUM_SAMPLES; i++)
    119                 sum += (double)niter / ((double)dsmp[i] / 1000000.0l);
    120 
    121         double avg = sum / NUM_SAMPLES;
    122 
    123         double qd = 0.0;
    124         double d;
    125         for (i = 0; i < NUM_SAMPLES; i++) {
    126                 d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;
    127                 qd += d * d;
    128         }
    129 
    130         double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt
    131 
    132         printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",
    133             avg, stddev, NUM_SAMPLES);
    134 
    135         return NULL;
    136 error:
    137         return msg;
    138 }
Note: See TracChangeset for help on using the changeset viewer.