Skip to content

Commit 019d063

Browse files
committed
update receiver footprint and add benchmark function
1 parent feb1bae commit 019d063

File tree

3 files changed

+142
-24
lines changed

3 files changed

+142
-24
lines changed

receiver.c

+56-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void init_config(struct config *config, int argc, char **argv) {
1313
// 4096 L1 stride
1414
int L1_way_stride = ipow(2, LOG_CACHE_SETS_L1 + LOG_CACHE_LINESIZE);
1515
// (4 * 64) * 8 * 4k = 8M
16-
uint64_t bsize = 256 * CACHE_WAYS_L1 * L1_way_stride;
16+
uint64_t bsize = 512 * CACHE_WAYS_L1 * L1_way_stride;
1717

1818
// Allocate a buffer twice the size of the L1 cache
1919
config->buffer = allocate_buffer(bsize);
@@ -26,7 +26,7 @@ void init_config(struct config *config, int argc, char **argv) {
2626
// Construct the addr_set by taking the addresses that have cache set index 0
2727
// There will be at least one of such addresses in our buffer.
2828
uint32_t addr_set_size = 0;
29-
for (int i = 0; i < 256 * CACHE_WAYS_L1 * CACHE_SETS_L1; i++) {
29+
for (int i = 0; i < 512 * CACHE_WAYS_L1 * CACHE_SETS_L1; i++) {
3030
ADDR_PTR addr = (ADDR_PTR) (config->buffer + CACHE_LINESIZE * i);
3131
// both of following function should work...L3 is a more restrict set
3232
if (get_cache_slice_set_index(addr) == config->cache_region) {
@@ -40,7 +40,7 @@ void init_config(struct config *config, int argc, char **argv) {
4040
}
4141
// more lines than private cache ways helps to put more lines
4242
// into llc slices, increasing chance of to conflict with sender
43-
else if (addr_set_size >= 3 * (CACHE_WAYS_L1 + CACHE_WAYS_L2)) {
43+
else if (addr_set_size >= 5 * (CACHE_WAYS_L1 + CACHE_WAYS_L2)) {
4444
break;
4545
}
4646
}
@@ -188,10 +188,58 @@ bool detect_bit_pp(const struct config *config, bool first_bit)
188188
// to be the same as the max size of the message in the starter code of the sender.
189189
// static const int MAX_BUFFER_LEN = 128 * 8;
190190

191+
void benchmark_receive(struct config *config_p) {
192+
uint32_t benchmarkSize = 8192;
193+
uint8_t *msg = (uint8_t *)malloc(sizeof(uint8_t) * benchmarkSize);
194+
uint64_t start_t, bench_start_t = 0, bench_end_t = 0;
195+
for (uint32_t i = 0; i < benchmarkSize; i++) {
196+
// sync every 1024 bits, detecting pilot signal again
197+
if ((i & 0x3ff) == 0) {
198+
bool curr = true, prev = true;
199+
int flip_sequence = 4;
200+
while (true) {
201+
start_t = cc_sync();
202+
curr = detect_bit(config_p, true);
203+
204+
if (flip_sequence == 0 && curr == 1 && prev == 1) {
205+
debug("pilot signal detected for round %u\r", i / 1024);
206+
start_t = cc_sync();
207+
bench_start_t = i == 0? start_t: bench_start_t;
208+
break;
209+
}
210+
else if (flip_sequence > 0 && curr != prev) {
211+
flip_sequence--;
212+
}
213+
else if (curr == prev) {
214+
flip_sequence = 4;
215+
}
216+
prev = curr;
217+
}
218+
}
219+
220+
msg[i] = detect_bit(config_p, true);
221+
222+
}
223+
bench_end_t = get_time();
224+
printf("total cycles to receive %u bits is %lu\n", benchmarkSize,
225+
bench_end_t - bench_start_t);
226+
227+
if (msg) {
228+
FILE *receiverSave = fopen("receiverSave", "w+");
229+
for (uint32_t i = 0; i < benchmarkSize; i++) {
230+
fprintf(receiverSave, "%u %u\n", i, msg[i]);
231+
}
232+
fclose(receiverSave);
233+
234+
free(msg);
235+
}
236+
}
237+
191238
int main(int argc, char **argv)
192239
{
193240
// Initialize config and local variables
194241
struct config config;
242+
195243
init_config(&config, argc, argv);
196244
if (config.channel == PrimeProbe || config.channel == L1DPrimeProbe) {
197245
detect_bit = detect_bit_pp;
@@ -206,6 +254,11 @@ int main(int argc, char **argv)
206254
bool current;
207255
bool previous = true;
208256

257+
if (config.benchmark_mode) {
258+
benchmark_receive(&config);
259+
exit(0);
260+
}
261+
209262
printf("Press enter to begin listening ");
210263
getchar();
211264
while (1) {

sender.c

+59-3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,53 @@ void send_bit_pp(bool one, const struct config *config)
156156
}
157157
}
158158

159+
uint8_t *generate_random_msg(uint32_t size) {
160+
uint8_t *msg = (uint8_t *)malloc(sizeof(uint8_t) * size);
161+
srand(time(NULL));
162+
for(uint32_t i = 0; i < size; i++) {
163+
int randomnum = rand();
164+
msg[i] = (randomnum > RAND_MAX/2);
165+
}
166+
return msg;
167+
}
168+
169+
void benchmark_send(struct config *config_p) {
170+
uint32_t benchmarkSize = 8192;
171+
uint8_t *randomMsg = generate_random_msg(benchmarkSize);
172+
uint64_t start_t;
173+
174+
for (uint32_t i = 0; i < benchmarkSize; i++) {
175+
// sync every 1024 bits
176+
if ((i & 0x3ff) == 0) {
177+
for (int j = 0; j < 10; j++) {
178+
start_t = cc_sync();
179+
send_bit(j % 2 == 0, config_p);
180+
}
181+
182+
start_t = cc_sync();
183+
send_bit(true, config_p);
184+
185+
start_t = cc_sync();
186+
send_bit(true, config_p);
187+
188+
// Send the message bit by bit
189+
debug("pilot signal sentt for round %u\r", i / 1024);
190+
start_t = cc_sync();
191+
}
192+
send_bit(randomMsg[i], config_p);
193+
}
194+
195+
if (randomMsg) {
196+
FILE *senderSave = fopen("senderSave", "w+");
197+
for (uint32_t i = 0; i < benchmarkSize; i++) {
198+
fprintf(senderSave, "%u %u\n", i, randomMsg[i]);
199+
}
200+
fclose(senderSave);
201+
202+
free(randomMsg);
203+
}
204+
}
205+
159206
int main(int argc, char **argv)
160207
{
161208
// Initialize config and local variables
@@ -168,17 +215,28 @@ int main(int argc, char **argv)
168215
send_bit = send_bit_fr;
169216
}
170217

218+
if (config.benchmark_mode) {
219+
benchmark_send(&config);
220+
exit(0);
221+
}
222+
171223
uint64_t start_t, end_t;
172224
int sending = 1;
173225
printf("Please type a message (exit to stop).\n");
226+
227+
#if 0
174228
char all_one_msg[129];
175229
for (uint32_t i = 0; i < 120; i++)
176230
all_one_msg[i] = '1';
177231
for (uint32_t i = 120; i < 128; i++)
178232
all_one_msg[i] = '1';
179233
all_one_msg[128] = '\0';
234+
#endif
235+
180236
while (sending) {
181-
#if 1
237+
#if 0
238+
char *msg = all_one_msg;
239+
#else
182240
// Get a message to send from the user
183241
printf("< ");
184242
char text_buf[128];
@@ -189,8 +247,6 @@ int main(int argc, char **argv)
189247
}
190248

191249
char *msg = string_to_binary(text_buf);
192-
#else
193-
char *msg = all_one_msg;
194250
#endif
195251

196252
// If we are in benchmark mode, start measuring the time

util.c

+27-18
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ uint64_t rdtsc() {
4242

4343
extern inline __attribute__((always_inline))
4444
CYCLES rdtscp(void) {
45-
CYCLES cycles;
46-
asm volatile ("rdtscp"
47-
: /* outputs */ "=a" (cycles));
45+
CYCLES cycles;
46+
asm volatile ("rdtscp"
47+
: /* outputs */ "=a" (cycles));
4848

49-
return cycles;
49+
return cycles;
5050
}
5151

5252
inline uint64_t get_time() {
@@ -109,7 +109,7 @@ void *allocate_buffer(uint64_t size) {
109109
#endif
110110

111111
if (buffer == MAP_FAILED) {
112-
fprintf(stderr, "allocating non-hugepages\n");
112+
fprintf(stderr, "WARNING: allocating non-hugepages\n");
113113
buffer = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
114114
}
115115
if (buffer == MAP_FAILED) {
@@ -200,7 +200,15 @@ uint64_t print_pid() {
200200
}
201201

202202
void print_help() {
203-
// TODO
203+
printf("======================= H E L P ===============================\n");
204+
printf("-c: (uint 0 to 2) to select a channel\n");
205+
printf("-i: (uint) to specify a interval for each bit transmission\n");
206+
printf("-p: (uint) to specify a time period for prime (for llc-pp)\n");
207+
printf("-a: (uint) to specify a time period for access (for llc-pp)\n");
208+
printf("-r: (uint) to specify a LLC cache set to contend on\n");
209+
printf("-b: to start benchmark mode (default is chat mode)\n");
210+
printf("-h: to print this message\n");
211+
printf("===============================================================\n");
204212
}
205213

206214
void init_default(struct config *config, int argc, char **argv) {
@@ -224,30 +232,31 @@ void init_default(struct config *config, int argc, char **argv) {
224232

225233
config->channel = PrimeProbe;
226234

227-
// Parse the command line flags
228-
// -d is used to enable the debug prints
229-
// -i is used to specify a custom value for the time interval
230-
// -w is used to specify a custom number of wait time between two probes
231235
int option;
232-
while ((option = getopt(argc, argv, "di:a:r:c:")) != -1) {
236+
while ((option = getopt(argc, argv, "c:i:p:a:r:bh")) != -1) {
233237
switch (option) {
238+
case 'c':
239+
// value 0,1,2 to select channel
240+
config->channel = atoi(optarg);
241+
break;
234242
case 'i':
235243
config->interval = atoi(optarg);
236244
break;
237-
case 'r':
238-
config->cache_region = atoi(optarg);
245+
case 'p':
246+
config->prime_period = atoi(optarg);
239247
break;
240248
case 'a':
241249
config->access_period = atoi(optarg);
242250
break;
243-
case 'c':
244-
// value 0,1,2 to select channel
245-
config->channel = atoi(optarg);
251+
case 'r':
252+
config->cache_region = atoi(optarg);
253+
break;
254+
case 'b':
255+
config->benchmark_mode = true;
246256
break;
247257
case '?':
248258
fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
249-
print_help();
250-
exit(1);
259+
case 'h':
251260
default:
252261
print_help();
253262
exit(1);

0 commit comments

Comments
 (0)