Changeset 3bd74758 in mainline
- Timestamp:
- 2018-12-28T09:32:11Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c7de81b
- Parents:
- 8ee106b
- Location:
- uspace/app/perf
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/perf/ipc/ns_ping.c
r8ee106b r3bd74758 27 27 */ 28 28 29 #include <math.h>30 29 #include <stdio.h> 31 #include <stdlib.h>32 #include <time.h>33 30 #include <ns.h> 34 31 #include <async.h> 35 32 #include <errno.h> 33 #include <str_error.h> 36 34 #include "../perf.h" 37 35 38 #define MIN_DURATION_SECS 10 39 #define NUM_SAMPLES 10 36 bool bench_ns_ping(stopwatch_t *stopwatch, uint64_t niter, 37 char *error, size_t error_size) 38 { 39 stopwatch_start(stopwatch); 40 40 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(); 45 43 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; 54 49 } 55 50 } 56 51 57 struct timespec now; 58 getuptime(&now); 52 stopwatch_stop(stopwatch); 59 53 60 *rduration = ts_sub_diff(&now, &start) / 1000; 61 return EOK; 54 return true; 62 55 } 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 sqrt129 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 } -
uspace/app/perf/ipc/ns_ping.def
r8ee106b r3bd74758 2 2 "ns_ping", 3 3 "Name service IPC ping-pong benchmark", 4 &bench_ns_ping 4 &bench_ns_ping, 5 NULL, NULL 5 6 }, -
uspace/app/perf/ipc/ping_pong.c
r8ee106b r3bd74758 27 27 */ 28 28 29 #include <math.h>30 29 #include <stdio.h> 31 #include <stdlib.h>32 #include <time.h>33 30 #include <ipc_test.h> 34 31 #include <async.h> 35 32 #include <errno.h> 33 #include <str_error.h> 36 34 #include "../perf.h" 37 35 38 #define MIN_DURATION_SECS 10 39 #define NUM_SAMPLES 10 36 static ipc_test_t *test = NULL; 40 37 41 static errno_t ping_pong_measure(ipc_test_t *test, uint64_t niter, 42 uint64_t *rduration) 38 bool bench_ping_pong_setup(char *error, size_t error_size) 43 39 { 44 struct timespec start; 45 uint64_t count; 40 errno_t rc = ipc_test_create(&test); 41 if (rc != EOK) { 42 snprintf(error, error_size, 43 "failed contacting IPC test server: %s (%d)", 44 str_error(rc), rc); 45 return false; 46 } 46 47 47 getuptime(&start); 48 return true; 49 } 48 50 49 for (count = 0; count < niter; count++) { 50 errno_t retval = ipc_test_ping(test); 51 bool bench_ping_pong_teardown(char *error, size_t error_size) 52 { 53 ipc_test_destroy(test); 54 return true; 55 } 51 56 52 if (retval != EOK) { 53 printf("Error sending ping message.\n"); 54 return EIO; 57 bool bench_ping_pong(stopwatch_t *stopwatch, uint64_t niter, 58 char *error, size_t error_size) 59 { 60 stopwatch_start(stopwatch); 61 62 for (uint64_t count = 0; count < niter; count++) { 63 errno_t rc = ipc_test_ping(test); 64 65 if (rc != EOK) { 66 snprintf(error, error_size, 67 "failed sending ping message: %s (%d)", 68 str_error(rc), rc); 69 return false; 55 70 } 56 71 } 57 72 58 struct timespec now; 59 getuptime(&now); 73 stopwatch_stop(stopwatch); 60 74 61 *rduration = ts_sub_diff(&now, &start) / 1000; 62 return EOK; 75 return true; 63 76 } 64 65 static void ping_pong_report(uint64_t niter, uint64_t duration)66 {67 printf("Completed %" PRIu64 " round trips in %" PRIu64 " us",68 niter, duration);69 70 if (duration > 0) {71 printf(", %" PRIu64 " rt/s.\n", niter * 1000 * 1000 / duration);72 } else {73 printf(".\n");74 }75 }76 77 const char *bench_ping_pong(void)78 {79 errno_t rc;80 uint64_t duration;81 uint64_t dsmp[NUM_SAMPLES];82 ipc_test_t *test;83 const char *msg;84 85 rc = ipc_test_create(&test);86 if (rc != EOK)87 return "Failed contacting IPC test server.";88 89 printf("Warm up and determine work size...\n");90 91 struct timespec start;92 getuptime(&start);93 94 uint64_t niter = 1;95 96 while (true) {97 rc = ping_pong_measure(test, niter, &duration);98 if (rc != EOK) {99 msg = "Failed.";100 goto error;101 }102 103 ping_pong_report(niter, duration);104 105 if (duration >= MIN_DURATION_SECS * 1000000)106 break;107 108 niter *= 2;109 }110 111 printf("Measure %d samples...\n", NUM_SAMPLES);112 113 int i;114 115 for (i = 0; i < NUM_SAMPLES; i++) {116 rc = ping_pong_measure(test, niter, &dsmp[i]);117 if (rc != EOK) {118 msg = "Failed.";119 goto error;120 }121 122 ping_pong_report(niter, dsmp[i]);123 }124 125 double sum = 0.0;126 127 for (i = 0; i < NUM_SAMPLES; i++)128 sum += (double)niter / ((double)dsmp[i] / 1000000.0l);129 130 double avg = sum / NUM_SAMPLES;131 132 double qd = 0.0;133 double d;134 for (i = 0; i < NUM_SAMPLES; i++) {135 d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;136 qd += d * d;137 }138 139 double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt140 141 printf("Average: %.0f rt/s Std.dev^2: %.0f rt/s Samples: %d\n",142 avg, stddev, NUM_SAMPLES);143 144 ipc_test_destroy(test);145 return NULL;146 error:147 ipc_test_destroy(test);148 return msg;149 } -
uspace/app/perf/ipc/ping_pong.def
r8ee106b r3bd74758 2 2 "ping_pong", 3 3 "IPC ping-pong benchmark", 4 &bench_ping_pong 4 &bench_ping_pong, 5 &bench_ping_pong_setup, &bench_ping_pong_teardown 5 6 }, -
uspace/app/perf/malloc/malloc1.c
r8ee106b r3bd74758 30 30 #include <stdio.h> 31 31 #include <stdlib.h> 32 #include <time.h>33 #include <errno.h>34 32 #include "../perf.h" 35 33 36 #define MIN_DURATION_SECS 10 37 #define NUM_SAMPLES 10 38 39 static errno_t malloc1_measure(uint64_t niter, uint64_t *rduration) 34 bool bench_malloc1(stopwatch_t *stopwatch, uint64_t size, 35 char *error, size_t error_size) 40 36 { 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 } 51 46 free(p); 52 47 } 48 stopwatch_stop(stopwatch); 53 49 54 struct timespec now; 55 getuptime(&now); 56 57 *rduration = ts_sub_diff(&now, &start) / 1000; 58 return EOK; 50 return true; 59 51 } 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 sqrt131 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 } -
uspace/app/perf/malloc/malloc1.def
r8ee106b r3bd74758 2 2 "malloc1", 3 3 "User-space memory allocator benchmark, repeatedly allocate one block", 4 &bench_malloc1 4 &bench_malloc1, 5 NULL, NULL 5 6 }, -
uspace/app/perf/malloc/malloc2.c
r8ee106b r3bd74758 27 27 */ 28 28 29 #include < math.h>29 #include <stdlib.h> 30 30 #include <stdio.h> 31 #include <stdlib.h>32 #include <time.h>33 #include <errno.h>34 31 #include "../perf.h" 35 32 36 #define MIN_DURATION_SECS 10 37 #define NUM_SAMPLES 10 33 bool bench_malloc2(stopwatch_t *stopwatch, uint64_t niter, 34 char *error, size_t error_size) 35 { 36 stopwatch_start(stopwatch); 38 37 39 static errno_t malloc2_measure(uint64_t niter, uint64_t *rduration) 40 { 41 struct timespec start; 42 uint64_t count; 43 void **p; 44 45 getuptime(&start); 46 47 p = malloc(niter * sizeof(void *)); 48 if (p == NULL) 49 return ENOMEM; 50 51 for (count = 0; count < niter; count++) { 52 p[count] = malloc(1); 53 if (p[count] == NULL) 54 return ENOMEM; 38 void **p = malloc(niter * sizeof(void *)); 39 if (p == NULL) { 40 snprintf(error, error_size, 41 "failed to allocate backend array (%" PRIu64 "B)", 42 niter * sizeof(void *)); 43 return false; 55 44 } 56 45 57 for (count = 0; count < niter; count++) 46 for (uint64_t count = 0; count < niter; count++) { 47 p[count] = malloc(1); 48 if (p[count] == NULL) { 49 snprintf(error, error_size, 50 "failed to allocate 1B in run %" PRIu64 " (out of %" PRIu64 ")", 51 count, niter); 52 for (uint64_t j = 0; j < count; j++) { 53 free(p[j]); 54 } 55 free(p); 56 return false; 57 } 58 } 59 60 for (uint64_t count = 0; count < niter; count++) 58 61 free(p[count]); 59 62 60 63 free(p); 61 64 62 struct timespec now; 63 getuptime(&now); 65 stopwatch_stop(stopwatch); 64 66 65 *rduration = ts_sub_diff(&now, &start) / 1000; 66 return EOK; 67 return true; 67 68 } 68 69 static void malloc2_report(uint64_t niter, uint64_t duration)70 {71 printf("Completed %" PRIu64 " allocations and deallocations in %" PRIu64 " us",72 niter, duration);73 74 if (duration > 0) {75 printf(", %" PRIu64 " cycles/s.\n", niter * 1000 * 1000 / duration);76 } else {77 printf(".\n");78 }79 }80 81 const char *bench_malloc2(void)82 {83 errno_t rc;84 uint64_t duration;85 uint64_t dsmp[NUM_SAMPLES];86 const char *msg;87 88 printf("Warm up and determine work size...\n");89 90 struct timespec start;91 getuptime(&start);92 93 uint64_t niter = 1;94 95 while (true) {96 rc = malloc2_measure(niter, &duration);97 if (rc != EOK) {98 msg = "Failed.";99 goto error;100 }101 102 malloc2_report(niter, duration);103 104 if (duration >= MIN_DURATION_SECS * 1000000)105 break;106 107 niter *= 2;108 }109 110 printf("Measure %d samples...\n", NUM_SAMPLES);111 112 int i;113 114 for (i = 0; i < NUM_SAMPLES; i++) {115 rc = malloc2_measure(niter, &dsmp[i]);116 if (rc != EOK) {117 msg = "Failed.";118 goto error;119 }120 121 malloc2_report(niter, dsmp[i]);122 }123 124 double sum = 0.0;125 126 for (i = 0; i < NUM_SAMPLES; i++)127 sum += (double)niter / ((double)dsmp[i] / 1000000.0l);128 129 double avg = sum / NUM_SAMPLES;130 131 double qd = 0.0;132 double d;133 for (i = 0; i < NUM_SAMPLES; i++) {134 d = (double)niter / ((double)dsmp[i] / 1000000.0l) - avg;135 qd += d * d;136 }137 138 double stddev = qd / (NUM_SAMPLES - 1); // XXX sqrt139 140 printf("Average: %.0f cycles/s Std.dev^2: %.0f cycles/s Samples: %d\n",141 avg, stddev, NUM_SAMPLES);142 143 return NULL;144 error:145 return msg;146 } -
uspace/app/perf/malloc/malloc2.def
r8ee106b r3bd74758 2 2 "malloc2", 3 3 "User-space memory allocator benchmark, allocate many small blocks", 4 &bench_malloc2 4 &bench_malloc2, 5 NULL, NULL 5 6 }, -
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 -
uspace/app/perf/perf.h
r8ee106b r3bd74758 37 37 38 38 #include <stdbool.h> 39 #include <perf.h> 39 40 40 typedef const char *(*benchmark_entry_t)(void); 41 typedef bool (*benchmark_entry_t)(stopwatch_t *, uint64_t, 42 char *, size_t); 43 typedef bool (*benchmark_helper_t)(char *, size_t); 41 44 42 45 typedef struct { … … 44 47 const char *desc; 45 48 benchmark_entry_t entry; 49 benchmark_helper_t setup; 50 benchmark_helper_t teardown; 46 51 } benchmark_t; 47 52 48 extern const char *bench_malloc1(void); 49 extern const char *bench_malloc2(void); 50 extern const char *bench_ns_ping(void); 51 extern const char *bench_ping_pong(void); 53 extern bool bench_malloc1(stopwatch_t *, uint64_t, char *, size_t); 54 extern bool bench_malloc2(stopwatch_t *, uint64_t, char *, size_t); 55 extern bool bench_ns_ping(stopwatch_t *, uint64_t, char *, size_t); 56 extern bool bench_ping_pong(stopwatch_t *, uint64_t, char *, size_t); 57 extern bool bench_ping_pong_setup(char *, size_t); 58 extern bool bench_ping_pong_teardown(char *, size_t); 52 59 53 60 extern benchmark_t benchmarks[];
Note:
See TracChangeset
for help on using the changeset viewer.