Changeset 3bd74758 in mainline for uspace/app/perf/perf.c
- Timestamp:
- 2018-12-28T09:32:11Z (5 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c7de81b
- Parents:
- 8ee106b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/perf/perf.c
r8ee106b r3bd74758 1 1 /* 2 2 * Copyright (c) 2018 Jiri Svoboda 3 * Copyright (c) 2018 Vojtech Horky 3 4 * All rights reserved. 4 5 * … … 38 39 #include <stdlib.h> 39 40 #include <str.h> 41 #include <time.h> 42 #include <errno.h> 43 #include <perf.h> 40 44 #include "perf.h" 45 46 #define MIN_DURATION_SECS 10 47 #define NUM_SAMPLES 10 48 #define MAX_ERROR_STR_LENGTH 1024 41 49 42 50 benchmark_t benchmarks[] = { … … 45 53 #include "malloc/malloc1.def" 46 54 #include "malloc/malloc2.def" 47 { NULL, NULL, NULL }55 { NULL, NULL, NULL, NULL, NULL } 48 56 }; 49 57 58 static void short_report(stopwatch_t *stopwatch, int run_index, 59 benchmark_t *bench, size_t workload_size) 60 { 61 usec_t duration_usec = NSEC2USEC(stopwatch_get_nanos(stopwatch)); 62 63 printf("Completed %zu operations in %llu us", 64 workload_size, duration_usec); 65 if (duration_usec > 0) { 66 double cycles = workload_size * 1000 * 1000 / duration_usec; 67 printf(", %.0f cycles/s.\n", cycles); 68 } else { 69 printf(".\n"); 70 } 71 } 72 73 static void summary_stats(stopwatch_t *stopwatch, size_t stopwatch_count, 74 benchmark_t *bench, size_t workload_size) 75 { 76 double sum = 0.0; 77 double sum_square = 0.0; 78 79 for (size_t i = 0; i < stopwatch_count; i++) { 80 double nanos = stopwatch_get_nanos(&stopwatch[i]); 81 double thruput = (double) workload_size / (nanos / 1000000000.0l); 82 sum += thruput; 83 sum_square += thruput * thruput; 84 } 85 86 double avg = sum / stopwatch_count; 87 88 double sd_numer = sum_square + stopwatch_count * avg * avg - 2 * sum * avg; 89 double sd_square = sd_numer / ((double) stopwatch_count - 1); 90 91 printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %zu\n", 92 avg, sd_square, stopwatch_count); 93 } 94 50 95 static bool run_benchmark(benchmark_t *bench) 51 96 { 52 /* Execute the benchmarl */ 53 const char *ret = bench->entry(); 54 55 if (ret == NULL) { 56 printf("\nBenchmark completed\n"); 57 return true; 58 } 59 60 printf("\n%s\n", ret); 61 return false; 97 printf("Warm up and determine workload size...\n"); 98 99 char *error_msg = malloc(MAX_ERROR_STR_LENGTH + 1); 100 if (error_msg == NULL) { 101 printf("Out of memory!\n"); 102 return false; 103 } 104 str_cpy(error_msg, MAX_ERROR_STR_LENGTH, ""); 105 106 bool ret = true; 107 108 if (bench->setup != NULL) { 109 ret = bench->setup(error_msg, MAX_ERROR_STR_LENGTH); 110 if (!ret) { 111 goto leave_error; 112 } 113 } 114 115 size_t workload_size = 1; 116 117 while (true) { 118 stopwatch_t stopwatch = STOPWATCH_INITIALIZE_STATIC; 119 120 bool ok = bench->entry(&stopwatch, workload_size, 121 error_msg, MAX_ERROR_STR_LENGTH); 122 if (!ok) { 123 goto leave_error; 124 } 125 short_report(&stopwatch, -1, bench, workload_size); 126 127 nsec_t duration = stopwatch_get_nanos(&stopwatch); 128 if (duration > SEC2NSEC(MIN_DURATION_SECS)) { 129 break; 130 } 131 workload_size *= 2; 132 } 133 134 printf("Workload size set to %zu, measuring %d samples.\n", workload_size, NUM_SAMPLES); 135 136 stopwatch_t *stopwatch = calloc(NUM_SAMPLES, sizeof(stopwatch_t)); 137 if (stopwatch == NULL) { 138 snprintf(error_msg, MAX_ERROR_STR_LENGTH, "failed allocating memory"); 139 goto leave_error; 140 } 141 for (int i = 0; i < NUM_SAMPLES; i++) { 142 stopwatch_init(&stopwatch[i]); 143 144 bool ok = bench->entry(&stopwatch[i], workload_size, 145 error_msg, MAX_ERROR_STR_LENGTH); 146 if (!ok) { 147 free(stopwatch); 148 goto leave_error; 149 } 150 short_report(&stopwatch[i], i, bench, workload_size); 151 } 152 153 summary_stats(stopwatch, NUM_SAMPLES, bench, workload_size); 154 printf("\nBenchmark completed\n"); 155 156 free(stopwatch); 157 158 goto leave; 159 160 leave_error: 161 printf("Error: %s\n", error_msg); 162 ret = false; 163 164 leave: 165 if (bench->teardown != NULL) { 166 bool ok = bench->teardown(error_msg, MAX_ERROR_STR_LENGTH); 167 if (!ok) { 168 printf("Error: %s\n", error_msg); 169 ret = false; 170 } 171 } 172 173 free(error_msg); 174 175 return ret; 62 176 } 63 177
Note:
See TracChangeset
for help on using the changeset viewer.