#define _GNU_SOURCE 500
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <string.h>
void test1(double *a, double *b, double *c, double *d,
unsigned int rounds, unsigned int array_size)
{
unsigned int i, j;
for (i = 0; i < rounds; i++) {
for (j = 0; j < array_size; j++) {
a[j] += b[j];
c[j] += d[j];
}
}
}
void test2(double *a, double *b, double *c, double *d,
unsigned int rounds, unsigned int array_size)
{
unsigned int i, j;
for (i = 0; i < rounds; i++) {
for (j = 0; j < array_size; j++)
a[j] += b[j];
for (j = 0; j < array_size; j++)
c[j] += d[j];
}
}
int main(int argc, char *argv[])
{
struct timespec s, e;
unsigned int array_size, offset, i, size, t, junk = 256000;
unsigned long diff, sum, min;
double *a, *b0, *b, *c0, *c, *d0, *d;
if (argc != 3) {
printf("Usage: %s <array_size> <offset>\n", argv[0]);
return 1;
}
array_size = strtoul(argv[1], NULL, 10);
offset = strtoul(argv[2], NULL, 10);
/* a */
size = array_size * sizeof(double) + junk;
a = (double *) malloc(size);
if (a == NULL) {
printf("Cannot alloc %u bytes!\n", size);
return 1;
}
/* b */
size = offset + array_size * sizeof(double) + junk;
b0 = (double *) malloc(size);
if (b0 == NULL) {
printf("Cannot alloc %u bytes!\n", size);
return 1;
}
b = (double *) ((unsigned char *) b0 + offset);
/* c */
size = offset * 2 + array_size * sizeof(double) + junk;
c0 = (double *) malloc(size);
if (c0 == NULL) {
printf("Cannot alloc %u bytes!\n", size);
return 1;
}
c = (double *) ((unsigned char *) c0 + offset * 2);
/* d */
size = offset * 3 + array_size * sizeof(double) + junk;
d0 = (double *) malloc(size);
if (d0 == NULL) {
printf("Cannot alloc %u bytes!\n", size);
return 1;
}
d = (double *) ((unsigned char *) d0 + offset * 3);
printf("array_size=%u array_size_bytes=%lu offset=%u"
" a=%p b=%p c=%p d=%p"
" b-a=%x c-a=%x d-a=%x\n",
array_size, array_size * sizeof(double), offset,
a, b, c, d,
abs(b - a), abs(c - a), abs(d - a));
for (t = 1; t <= 2; t++) {
sum = 0;
min = 0;
printf(" elap%u=", t);
for (i = 0; i < 10; i++) {
size = array_size * sizeof(double);
memset(a, 0, size);
memset(b, 0, size);
memset(c, 0, size);
memset(d, 0, size);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &s);
if (t == 1)
test1(a, b, c, d, 1, array_size);
else
test2(a, b, c, d, 1, array_size);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &e);
diff = (e.tv_sec - s.tv_sec) * 1000000 + (e.tv_nsec - s.tv_nsec) / 1000;
printf(",%lu.%06lus",
diff / 1000000, diff % 1000000);
sum += diff;
if (min == 0)
min = diff;
if (min > diff)
min = diff;
}
printf(" avg[%u]=%lu.%06lu min[%u]=%lu.%06lus\n",
t, sum / 10 / 1000000, (sum / 10) % 1000000,
t, min / 1000000, min % 1000000);
}
printf("\n");
free(d0);
free(c0);
free(b0);
free(a);
return 0;
}