-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsequential.c
116 lines (100 loc) · 2.33 KB
/
sequential.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
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#define PAGE_SIZE 4096
#define NR_BUFF 1
#define MODE_READ_ONLY 0
#define MODE_WRITE_ONLY 1
#define MODE_READ_WRITE 2
#define MODE_WRITE_READ 3
/*
* Touch first byte of each 4KB region successively
* from both the buffers. We do not care about address
* alignment here as PAZE_SIZE would always ensure we are
* actually moving to the next physical page.
*/
static void access_buffers(char *b1, char *b2, int mode)
{
char *start = b1;
char *end = b1 + (1<<30);
char var;
int repeated = 0;
repeat:
while (start < end) {
if (mode == MODE_READ_ONLY)
var = *start;
else if (mode == MODE_WRITE_ONLY)
*start = 'A';
else if (mode == MODE_READ_WRITE) {
var = *start;
*start = 'A';
}
else {
*start = 'A';
var = *start;
}
start += PAGE_SIZE;
}
/* Prepare pointers to traverse the second buffer.*/
start = b2;
end = b2 + (1<<30);
/* If both the buffers are traversed, return. */
if (repeated)
return;
repeated = 1;
goto repeat;
/* Should never reach here. */
assert(0);
}
/*
* Touch pages to force page allocation and warm the cache.
*/
static void do_fault_buffer(char *buff)
{
char *start = buff;
char *end = buff + (1<<30);
while (start < end) {
*start = 'A';
start += PAGE_SIZE;
}
}
int main(int argc, char *argv[])
{
char *buff1[NR_BUFF], *buff2[NR_BUFF];
char mode_str[4][12] = {"READ_ONLY\0","WRITE_ONLY\0",
"READ_WRITE\0","WRITE_READ\0"};
int i, j, iteration, mode = -1;
if (argc != 3) {
printf("Usage: ./sequential mode iteration\n");
exit(1);
}
/* Accept and parse arguments.*/
mode = atoi(argv[1]);
iteration = atoi(argv[2]);
assert(mode >= 0 && mode <= 3);
/* Allocate empty buffers */
for (i = 0; i < NR_BUFF; i++) {
buff1[i] = malloc(1<<30);
buff2[i] = malloc(1<<30);
if (!buff1[i] || !buff2[i]) {
printf("Buffer allocation failed\n");
exit(1);
}
}
printf("Buffer are ready to be used.\n");
printf("Generating faults to allocate pages.\n");
for (i = 0; i < NR_BUFF; i++) {
do_fault_buffer(buff1[i]);
do_fault_buffer(buff2[i]);
}
printf("Accessing buffers in %s mode\n", mode_str[mode]);
for (i=1; i<=iteration; i++) {
if (i%1000 == 0)
printf("Iteration Completed: %d\n", i);
for (j=0; j<NR_BUFF; j++) {
access_buffers(buff1[j], buff2[j], mode);
}
}
return 0;
}