Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/perf/malloc/malloc1.c

    rd5caf79 re131833c  
    3030#include <stdio.h>
    3131#include <stdlib.h>
    32 #include "../benchlist.h"
     32#include <time.h>
     33#include <errno.h>
    3334#include "../perf.h"
    3435
    35 static bool runner(stopwatch_t *stopwatch, uint64_t size,
    36     char *error, size_t error_size)
     36#define MIN_DURATION_SECS  10
     37#define NUM_SAMPLES 10
     38
     39static errno_t malloc1_measure(uint64_t niter, uint64_t *rduration)
    3740{
    38         stopwatch_start(stopwatch);
    39         for (uint64_t i = 0; i < size; i++) {
    40                 void *p = malloc(1);
    41                 if (p == NULL) {
    42                         snprintf(error, error_size,
    43                             "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")",
    44                             i, size);
    45                         return false;
    46                 }
     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;
    4751                free(p);
    4852        }
    49         stopwatch_stop(stopwatch);
    5053
    51         return true;
     54        struct timespec now;
     55        getuptime(&now);
     56
     57        *rduration = ts_sub_diff(&now, &start) / 1000;
     58        return EOK;
    5259}
    5360
    54 benchmark_t bench_malloc1 = {
    55         .name = "malloc1",
    56         .desc = "User-space memory allocator benchmark, repeatedly allocate one block",
    57         .entry = &runner,
    58         .setup = NULL,
    59         .teardown = NULL
    60 };
     61static 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
     73const 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;
     136error:
     137        return msg;
     138}
Note: See TracChangeset for help on using the changeset viewer.