10
#define QUOTEME_(x) #x
11
#define QUOTEME(x) QUOTEME_(x)
13
#define NUM_ELEMS(_x) (sizeof(_x) / sizeof((_x)[0]))
16
#define VERSION "(unknown version)"
19
static const char* version = QUOTEME(VERSION);
21
/** Current wall time in seconds */
12
gettimeofday(&tv, NULL);
14
return tv.tv_sec + tv.tv_usec * 1e-6;
26
int err = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
29
return ts.tv_sec + ts.tv_nsec * 1e-9;
17
32
static int get_arg(int argc, char **argv, int idx, int fallback)
42
static void __attribute__((noinline)) xmemcpy(char *dest, char *src, size_t n)
57
static void xbounce(void *dest, void *src, size_t n)
61
static void xmemcpy(void *dest, void *src, size_t n)
44
63
memcpy(dest, src, n);
47
static void __attribute__((noinline)) xstrcpy(char *dest, char *src)
66
static void xmemset(void *dest, void *src, size_t n)
71
static void xstrcpy(void *dest, void *src, size_t n)
52
static void __attribute__((noinline)) xmemset(void *dest, int c, size_t n)
76
static void xstrlen(void *dest, void *src, size_t n)
81
static void xstrcmp(void *dest, void *src, size_t n)
86
typedef void (*stub_t)(void *dest, void *src, size_t n);
94
static const struct test tests[] =
96
{ "memcpy", xmemcpy },
97
{ "memset", xmemset },
98
{ "strcpy", xstrcpy },
99
{ "strlen", xstrlen },
100
{ "strcmp", xstrcmp },
101
{ "bounce", xbounce },
105
static void usage(const char* name)
107
printf("%s %s: run a string related benchmark.\n"
108
"usage: %s [-c block-size] [-l loop-count] [-f] [-t test-name]\n"
109
, name, version, name);
57
113
int main(int argc, char **argv)
59
115
char *src = calloc(1024, 1024);
60
116
char *dest = calloc(1024, 1024);
118
assert(src != NULL && dest != NULL);
64
122
for (int i = 0; i < 16*1024; i++)
66
124
src[i] = (char)random() | 1;
69
int count = get_arg(argc, argv, 1, 31);
70
int loops = get_arg(argc, argv, 2, 10000000);
71
int flush = get_arg(argc, argv, 3, 0);
128
int test_id = get_arg(argc, argv, 1, 0);
129
assert(test_id >= 0 && test_id <= NUM_ELEMS(tests));
132
int loops = 10000000;
134
const char *name = NULL;
137
while ((opt = getopt(argc, argv, "c:l:ft:hv")) > 0)
142
count = atoi(optarg);
145
loops = atoi(optarg);
151
name = strdup(optarg);
162
const struct test *ptest = NULL;
170
for (const struct test *p = tests; p->name != NULL; p++)
172
if (strcmp(p->name, name) == 0)
185
stub_t stub = ptest->stub;
75
190
double start = now();
77
192
for (int i = 0; i < loops; i++)
79
#if defined(WITH_MEMCPY)
80
xmemcpy(dest, src, count);
81
#elif defined(WITH_STRCPY)
83
#elif defined(WITH_MEMSET)
84
xmemset(src, 0, count);
194
(*stub)(dest, src, count);
95
202
double end = now();
96
203
double elapsed = end - start;
98
printf("%.3f for %u loops of %u bytes. %.3f MB/s\n", elapsed, loops, count, (double)loops*count/elapsed/(1024*1024));
205
printf("%s: %s: %.3f for %u loops of %u bytes. %.3f MB/s\n", QUOTEME(VARIANT), ptest->name, elapsed, loops, count, (double)loops*count/elapsed/(1024*1024));