-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathmtbench.c
More file actions
128 lines (116 loc) · 3.18 KB
/
mtbench.c
File metadata and controls
128 lines (116 loc) · 3.18 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
#include"min.h"
#include<stdio.h>
#include<stdlib.h>
#include<x86intrin.h>
#include<pthread.h>
#include<unistd.h>
#define THREADS 16
#define MAX (1024*1024)
#define HZ 3000000000
#define DURATION HZ*1
int array[MAX];
pthread_mutex_t lock;
pthread_barrier_t barrier;
int arrsize;
void* mutator_thread(void* voidrate) {
pthread_barrier_wait(&barrier);
long rate=(long)voidrate;
long interval=HZ/rate; // figuring 3 GHz
unsigned dummy;
long start_time=__rdtscp(&dummy);
long deadline=start_time+interval;
long after=0;
while(deadline<(start_time+DURATION)) { // 1 second experiment
pthread_mutex_lock(&lock);
array[after%arrsize]--;
array[(after+1)%arrsize]++;
pthread_mutex_unlock(&lock);
after=__rdtscp(&dummy);
if(after>deadline) {
printf("Mutator missed deadline for rate %ld.\n",rate);
return (void*)-1;
}
else { // wait until next time
do{
__pause();
after=__rdtscp(&dummy);
} while(after<deadline);
}
deadline+=interval;
}
return (void*)0;
}
void* scanner_thread(void* void_tid) {
// long tid = (long)void_tid;
pthread_mutex_lock(&lock);
long index=minindex(array,arrsize);
pthread_mutex_unlock(&lock);
return (void*)index;
}
pthread_mutex_t lock;
volatile int stop;
int scans;
void* scanner_main(void* unused) {
pthread_barrier_wait(&barrier);
stop=0;
scans=0;
while(!stop) {
pthread_t thread[THREADS];
for(long t=0;t<16;t++) {
pthread_create(&thread[t],0,scanner_thread,(void*)t);
}
int minindex = 0;
for(long t=0;t<16;t++) {
long index;
pthread_join(thread[t],(void**)&index);
if(array[minindex] > array[index]) {
minindex=index;
}
}
// scanner_thread(0);
scans++;
}
return 0;
}
int main(int argc, char** argv) {
int seed=789;
pthread_mutex_init(&lock,0);
#ifndef NOMUT
pthread_barrier_init(&barrier,0,3);
#else
pthread_barrier_init(&barrier,0,2);
#endif
for(int i=0;i<MAX;i++,seed+=789) {
array[i]=seed%MAX+12;
}
array[77]=-2;
for(long size=1024;size<=MAX;size*=2) {
arrsize=size;
for(long i=100;i<100000000;i*=2) {
#ifndef NOMUT
pthread_t mutator;
#endif
pthread_t scanner;
#ifndef NOMUT
pthread_create(&mutator,0,mutator_thread,(void*)i);
#endif
pthread_create(&scanner,0,scanner_main,(void*)0);
pthread_barrier_wait(&barrier);
void* mutator_return=(void*)0;
#ifndef NOMUT
pthread_join(mutator,&mutator_return);
#else
sleep(2);
#endif
stop=1;
pthread_join(scanner,0);
if(mutator_return != 0) {
break;
}
printf("size %ld rate %ld scans %d score %.1lf\n",size,i,scans,(double)size*(double)i*(double)scans/1000000.0);
#ifdef NOMUT
break;
#endif
}
}
}