-
Notifications
You must be signed in to change notification settings - Fork 3
/
exercise02_mem_hierarchy.c
104 lines (88 loc) · 3.17 KB
/
exercise02_mem_hierarchy.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/* Source: http://www.hpl.hp.com/research/cacti/aca_ch2_cs2.c */
//#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#define ARRAY_MIN (1024) /* 1/4 smallest cache */
#define ARRAY_MAX (4096*4096) /* 1/4 largest cache */
int x[ARRAY_MAX]; /* array going to stride through */
long get_seconds() { /* routine to read time in seconds */
//double get_seconds() { /* routine to read time in seconds */
//__time64_t ltime;
//_time64( <ime );
//return (double) ltime;
return time ( NULL ); // time in seconds
/*long usec;
struct timeval tp;
gettimeofday ( &tp, NULL );
usec = tp.tv_sec * 1E6 + tp.tv_usec;
return usec;*/
}
int label(int i) {/* generate text labels */
if (i<1e3) printf("%1dB,",i);
else if (i<1e6) printf("%1dK,",i/1024);
else if (i<1e9) printf("%1dM,",i/1048576);
else printf("%1dG,",i/1073741824);
return 0;
}
int main(int argc, char* argv[])
{
int register nextstep, i, index, stride;
int csize;
double steps, tsteps;
double loadtime, lastsec, sec0, sec1, sec; /* timing variables */
/* Initialize output */
printf(" ,");
for (stride=1; stride <= ARRAY_MAX/2; stride=stride*2)
label(stride*sizeof(int));
printf("\n");
/* Main loop for each configuration */
for (csize=ARRAY_MIN; csize <= ARRAY_MAX; csize=csize*2)
{
label(csize*sizeof(int)); /* print cache size this loop */
for (stride=1; stride <= csize/2; stride=stride*2) {
/* Lay out path of memory references in array */
for (index=0; index < csize; index=index+stride)
x[index] = index + stride; /* pointer to next */
x[index-stride] = 0; /* loop back to beginning */
/* Wait for timer to roll over */
lastsec = get_seconds();
do sec0 = get_seconds(); while (sec0 == lastsec);
/* Walk through path in array for twenty seconds */
/* This gives 5% accuracy with second resolution */
steps = 0.0; /* number of steps taken */
nextstep = 0; /* start at beginning of path */
sec0 = get_seconds(); /* start timer */
do { /* repeat until collect 20 seconds */
for (i=stride;i!=0;i=i-1) { /* keep samples same */
nextstep = 0;
do nextstep = x[nextstep]; /* dependency */
while (nextstep != 0);
}
steps = steps + 1.0; /* count loop iterations */
sec1 = get_seconds(); /* end timer */
//} while ((sec1 - sec0) < 5000000); // collect .5 seconds
} while ((sec1 - sec0) < 20); /* collect 20 seconds */
sec = sec1 - sec0;
/* Repeat empty loop to loop subtract overhead */
tsteps = 0.0; /* used to match no. while iterations */
sec0 = get_seconds(); /* start timer */
do { /* repeat until same no. iterations as above */
for (i=stride;i!=0;i=i-1) { /* keep samples same */
index = 0;
do index = index + stride;
while (index < csize);
}
tsteps = tsteps + 1.0;
sec1 = get_seconds(); /* - overhead */
} while (tsteps<steps); /* until = no. iterations */
sec = sec - (sec1 - sec0);
//sec /= 1E6;
loadtime = (sec*1e9)/(steps*csize);
/* write out results in .csv format for Excel */
printf("%4.1f,", (loadtime<0.1) ? 0.1 : loadtime);
}; /* end of inner for loop */
printf("\n");
}; /* end of outer for loop */
return 0;
}