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

« back to all changes in this revision

Viewing changes to benchmarks/multi/harness.c

  • Committer: Will Newton
  • Date: 2013-06-21 14:42:10 UTC
  • Revision ID: will.newton@linaro.org-20130621144210-za4jb0kw9d4mcnml
Allow aligning source and destination buffers separately.

Show diffs side-by-side

added added

removed removed

Lines of Context:
39
39
#include <stdbool.h>
40
40
#include <assert.h>
41
41
#include <unistd.h>
42
 
#include <assert.h>
 
42
#include <errno.h>
43
43
 
44
44
#define NUM_ELEMS(_x) (sizeof(_x) / sizeof((_x)[0]))
45
45
 
153
153
static void usage(const char* name)
154
154
{
155
155
  printf("%s %s: run a string related benchmark.\n"
156
 
         "usage: %s [-c block-size] [-l loop-count] [-a alignment] [-f] [-t test-name]\n"
 
156
         "usage: %s [-c block-size] [-l loop-count] [-a alignment|src_alignment:dst_alignment] [-f] [-t test-name]\n"
157
157
         , name, VERSION, name);
158
158
 
159
159
  printf("Tests:");
189
189
  return NULL;
190
190
}
191
191
 
 
192
#define MIN_BUFFER_SIZE 1024*1024
 
193
#define MAX_ALIGNMENT   256
 
194
 
192
195
/** Take a pointer and ensure that the lower bits == alignment */
193
196
static char *realign(char *p, int alignment)
194
197
{
195
 
  if (alignment < 0)
196
 
    {
197
 
      return p;
198
 
    }
199
 
 
200
198
  uintptr_t pp = (uintptr_t)p;
201
 
  pp = (pp + 255) & ~255;
 
199
  pp = (pp + (MAX_ALIGNMENT - 1)) & ~(MAX_ALIGNMENT - 1);
202
200
  pp += alignment;
203
201
 
204
202
  return (char *)pp;
205
203
}
206
204
 
207
 
#define MIN_BUFFER_SIZE 1024*1024
 
205
static int parse_int_arg(const char *arg, const char *exe_name)
 
206
{
 
207
  long int ret;
 
208
 
 
209
  errno = 0;
 
210
  ret = strtol(arg, NULL, 0);
 
211
 
 
212
  if (errno)
 
213
    {
 
214
      usage(exe_name);
 
215
    }
 
216
 
 
217
  return (int)ret;
 
218
}
 
219
 
 
220
static void parse_alignment_arg(const char *arg, const char *exe_name,
 
221
                                int *src_alignment, int *dst_alignment)
 
222
{
 
223
  long int ret;
 
224
  char *endptr;
 
225
 
 
226
  errno = 0;
 
227
  ret = strtol(arg, &endptr, 0);
 
228
 
 
229
  if (errno)
 
230
    {
 
231
      usage(exe_name);
 
232
    }
 
233
 
 
234
  *src_alignment = (int)ret;
 
235
 
 
236
  if (ret > 256 || ret < 1)
 
237
    {
 
238
      printf("Alignment should be in the range [1, 256].\n");
 
239
      usage(exe_name);
 
240
    }
 
241
 
 
242
  if (ret == 256)
 
243
    ret = 0;
 
244
 
 
245
  if (endptr && *endptr == ':')
 
246
    {
 
247
      errno = 0;
 
248
      ret = strtol(endptr + 1, NULL, 0);
 
249
 
 
250
      if (errno)
 
251
        {
 
252
          usage(exe_name);
 
253
        }
 
254
 
 
255
      if (ret > 256 || ret < 1)
 
256
        {
 
257
          printf("Alignment should be in the range [1, 256].\n");
 
258
          usage(exe_name);
 
259
        }
 
260
 
 
261
      if (ret == 256)
 
262
        ret = 0;
 
263
    }
 
264
 
 
265
  *dst_alignment = (int)ret;
 
266
}
208
267
 
209
268
/** Setup and run a test */
210
269
int main(int argc, char **argv)
220
279
  int flush = 0;
221
280
  /* Name of the test */
222
281
  const char *name = NULL;
223
 
  /* Alignment of both buffers */
224
 
  int alignment = 8;
 
282
  /* Alignment of buffers */
 
283
  int src_alignment = 8;
 
284
  int dst_alignment = 8;
225
285
 
226
286
  int opt;
227
287
 
230
290
      switch (opt)
231
291
        {
232
292
        case 'c':
233
 
          count = atoi(optarg);
 
293
          count = parse_int_arg(optarg, argv[0]);
234
294
          break;
235
295
        case 'l':
236
 
          loops = atoi(optarg);
 
296
          loops = parse_int_arg(optarg, argv[0]);
237
297
          break;
238
298
        case 'a':
239
 
          alignment = atoi(optarg);
 
299
          parse_alignment_arg(optarg, argv[0], &src_alignment, &dst_alignment);
240
300
          break;
241
301
        case 'f':
242
302
          flush = 1;
261
321
      usage(argv[0]);
262
322
    }
263
323
 
264
 
  if (alignment > 256 || alignment < 1)
265
 
    {
266
 
      printf("Alignment should be in the range [1, 256].\n");
267
 
      usage(argv[0]);
268
 
    }
269
 
 
270
 
  if (alignment == 256)
271
 
    alignment = 0;
272
 
 
273
 
  if (count + alignment + 256 > MIN_BUFFER_SIZE)
274
 
    {
275
 
      buffer_size = count + alignment + 256;
 
324
  if (count + MAX_ALIGNMENT * 2 > MIN_BUFFER_SIZE)
 
325
    {
 
326
      buffer_size = count + MAX_ALIGNMENT * 2;
276
327
    }
277
328
 
278
329
  /* Buffers to read and write from */
281
332
 
282
333
  assert(src != NULL && dest != NULL);
283
334
 
284
 
  src = realign(src, alignment);
285
 
  dest = realign(dest, alignment);
 
335
  src = realign(src, src_alignment);
 
336
  dest = realign(dest, dst_alignment);
286
337
 
287
338
  /* Fill the buffer with non-zero, reproducable random data */
288
339
  srandom(1539);
340
391
  double bounced = 0.448730 * loops / 50000000;
341
392
 
342
393
  /* Dump both machine and human readable versions */
343
 
  printf("%s:%s:%u:%u:%d:%.6f: took %.6f s for %u calls to %s of %u bytes.  ~%.3f MB/s corrected.\n", 
 
394
  printf("%s:%s:%u:%u:%d:%d:%.6f: took %.6f s for %u calls to %s of %u bytes.  ~%.3f MB/s corrected.\n", 
344
395
         variant + 4, ptest->name,
345
 
         count, loops, alignment,
 
396
         count, loops, src_alignment, dst_alignment,
346
397
         elapsed,
347
398
         elapsed, loops, ptest->name, count,
348
399
         (double)loops*count/(elapsed - bounced)/(1024*1024));