~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to benchmarks/multi/harness.c

  • Committer: Michael Hope
  • Date: 2010-08-31 21:05:08 UTC
  • Revision ID: michael.hope@linaro.org-20100831210508-74vjmc796totwug8
Fleshed out the test harness

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#include <string.h>
2
 
#include <sys/time.h>
 
2
#include <time.h>
3
3
#include <stdint.h>
4
4
#include <stdlib.h>
5
5
#include <stdio.h>
6
6
#include <stdbool.h>
7
 
 
 
7
#include <assert.h>
 
8
#include <unistd.h>
 
9
 
 
10
#define QUOTEME_(x) #x
 
11
#define QUOTEME(x) QUOTEME_(x)
 
12
 
 
13
#define NUM_ELEMS(_x) (sizeof(_x) / sizeof((_x)[0]))
 
14
 
 
15
#ifndef VERSION
 
16
#define VERSION "(unknown version)"
 
17
#endif
 
18
 
 
19
static const char* version = QUOTEME(VERSION);
 
20
 
 
21
/** Current wall time in seconds */
8
22
static double now()
9
23
{
10
 
  struct timeval tv;
11
 
 
12
 
  gettimeofday(&tv, NULL);
13
 
 
14
 
  return tv.tv_sec + tv.tv_usec * 1e-6;
 
24
  struct timespec ts;
 
25
 
 
26
  int err = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
 
27
  assert(err == 0);
 
28
 
 
29
  return ts.tv_sec + ts.tv_nsec * 1e-9;
15
30
}
16
31
 
17
32
static int get_arg(int argc, char **argv, int idx, int fallback)
39
54
    }
40
55
}
41
56
 
42
 
static void __attribute__((noinline)) xmemcpy(char *dest, char *src, size_t n)
 
57
static void xbounce(void *dest, void *src, size_t n)
 
58
{
 
59
}
 
60
 
 
61
static void xmemcpy(void *dest, void *src, size_t n)
43
62
{
44
63
  memcpy(dest, src, n);
45
64
}
46
65
 
47
 
static void __attribute__((noinline)) xstrcpy(char *dest, char *src)
 
66
static void xmemset(void *dest, void *src, size_t n)
 
67
{
 
68
  memset(dest, 0, n);
 
69
}
 
70
 
 
71
static void xstrcpy(void *dest, void *src, size_t n)
48
72
{
49
73
  strcpy(dest, src);
50
74
}
51
75
 
52
 
static void __attribute__((noinline)) xmemset(void *dest, int c, size_t n)
53
 
{
54
 
  memset(dest, c, n);
 
76
static void xstrlen(void *dest, void *src, size_t n)
 
77
{
 
78
  (void)strlen(dest);
 
79
}
 
80
 
 
81
static void xstrcmp(void *dest, void *src, size_t n)
 
82
{
 
83
  strcmp(dest, src);
 
84
}
 
85
 
 
86
typedef void (*stub_t)(void *dest, void *src, size_t n);
 
87
 
 
88
struct test
 
89
{
 
90
  const char *name;
 
91
  stub_t stub;
 
92
};
 
93
 
 
94
static const struct test tests[] =
 
95
{
 
96
  { "memcpy", xmemcpy },
 
97
  { "memset", xmemset },
 
98
  { "strcpy", xstrcpy },
 
99
  { "strlen", xstrlen },
 
100
  { "strcmp", xstrcmp },
 
101
  { "bounce", xbounce },
 
102
  { NULL }
 
103
};
 
104
 
 
105
static void usage(const char* name)
 
106
{
 
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);
 
110
  exit(-1);
55
111
}
56
112
 
57
113
int main(int argc, char **argv)
59
115
  char *src = calloc(1024, 1024);
60
116
  char *dest = calloc(1024, 1024);
61
117
 
 
118
  assert(src != NULL && dest != NULL);
 
119
 
62
120
  srandom(1539);
63
121
 
64
122
  for (int i = 0; i < 16*1024; i++)
65
123
    {
66
124
      src[i] = (char)random() | 1;
67
 
    }
68
 
 
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);
 
125
      dest[i] = src[i];
 
126
    }
 
127
 
 
128
  int test_id = get_arg(argc, argv, 1, 0);
 
129
  assert(test_id >= 0 && test_id <= NUM_ELEMS(tests));
 
130
 
 
131
  int count = 31;
 
132
  int loops = 10000000;
 
133
  int flush = 0;
 
134
  const char *name = NULL;
 
135
  int opt;
 
136
 
 
137
  while ((opt = getopt(argc, argv, "c:l:ft:hv")) > 0)
 
138
    {
 
139
      switch (opt)
 
140
        {
 
141
        case 'c':
 
142
          count = atoi(optarg);
 
143
          break;
 
144
        case 'l':
 
145
          loops = atoi(optarg);
 
146
          break;
 
147
        case 'f':
 
148
          flush = 1;
 
149
          break;
 
150
        case 't':
 
151
          name = strdup(optarg);
 
152
          break;
 
153
        case 'h':
 
154
          usage(argv[0]);
 
155
          break;
 
156
        default:
 
157
          usage(argv[0]);
 
158
          break;
 
159
        }
 
160
    }
 
161
 
 
162
  const struct test *ptest = NULL;
 
163
 
 
164
  if (name == NULL)
 
165
    {
 
166
      ptest = tests + 0;
 
167
    }
 
168
  else
 
169
    {
 
170
      for (const struct test *p = tests; p->name != NULL; p++)
 
171
        {
 
172
          if (strcmp(p->name, name) == 0)
 
173
            {
 
174
              ptest = p;
 
175
              break;
 
176
            }
 
177
        }
 
178
    }
 
179
 
 
180
  if (ptest == NULL)
 
181
    {
 
182
      usage(argv[0]);
 
183
    }
 
184
 
 
185
  stub_t stub = ptest->stub;
72
186
 
73
187
  src[count] = 0;
 
188
  dest[count] = 0;
74
189
 
75
190
  double start = now();
76
191
 
77
192
  for (int i = 0; i < loops; i++)
78
193
    {
79
 
#if defined(WITH_MEMCPY)
80
 
      xmemcpy(dest, src, count);
81
 
#elif defined(WITH_STRCPY)
82
 
      xstrcpy(dest, src);
83
 
#elif defined(WITH_MEMSET)
84
 
      xmemset(src, 0, count);
85
 
#else
86
 
#error
87
 
#endif
 
194
      (*stub)(dest, src, count);
88
195
 
89
196
      if (flush != 0)
90
197
        {
95
202
  double end = now();
96
203
  double elapsed = end - start;
97
204
 
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));
99
206
 
100
207
  return 0;
101
208
}
102