This source file includes following definitions.
- get_ts_gettimeofday
- main
- value_xfer_thread
- bind_me_to
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdbool.h>
20 #include <string.h>
21 #include <pthread.h>
22 #include <stdint.h>
23 #include <hwloc.h>
24 #include <sys/time.h>
25
26 #include "opal/sys/atomic.h"
27
28
29
30 #define MAX_VAL 32767
31
32 typedef struct {
33 int type;
34 union {
35 bool flag;
36 int integer;
37 int8_t int8;
38 int16_t int16;
39 int32_t int32;
40 int64_t int64;
41
42 } data;
43 } my_value_t;
44
45
46 typedef struct {
47 volatile bool working;
48 void *ptr;
49 } thread_handoff_t;
50
51
52 thread_handoff_t handoff;
53
54
55 bool time_to_stop = false;
56
57
58 #define PERC_INC 10.0
59 double perc_report_after = PERC_INC;
60 double perc_current = 0.0;
61
62
63 #define MB_MODE_NONE 0x0
64 #define MB_MODE_RMB 0x1
65 #define MB_MODE_WMB 0x2
66 #define MB_MODE_MB 0x4
67 #define MB_MODE_XMB 0x8
68 #define MB_MODE_ALL (MB_MODE_RMB | MB_MODE_WMB)
69 int mb_mode = MB_MODE_ALL;
70
71
72
73 static hwloc_topology_t topo;
74
75
76
77
78 #define OBJ_TYPE HWLOC_OBJ_CORE
79
80
81
82
83 double acc_time, start_time, stop_time, delta;
84 static double get_ts_gettimeofday(void) {
85 double ret;
86 struct timeval tv;
87 gettimeofday(&tv, NULL);
88 ret = tv.tv_sec;
89 ret += (double)tv.tv_usec / 1000000.0;
90 return ret;
91 }
92
93
94
95
96 void bind_me_to(bool main_thread);
97
98
99
100
101 void *value_xfer_thread(void *arg);
102
103
104
105
106 int main(int argc, char **argv) {
107 pthread_t support_thread;
108 int rc, i, max_iters = 10, cur_iter;
109 my_value_t *val = NULL;
110 int mode;
111
112
113
114
115 if( argc > 1 ) {
116 max_iters = atoi(argv[1]);
117 }
118 if( argc > 2 ) {
119 mode = atoi(argv[2]);
120 if( 0 > mode || mode > 5 ) {
121 printf("Error: Invalid mode %d\n"
122 "\tNone = 0\n"
123 "\tRMB = 1\n"
124 "\tWMB = 2\n"
125 "\tBoth = 3\n"
126 "\tMB Only = 4\n",
127 "\tXMB Only = 5\n",
128 mode);
129 exit(-1);
130 }
131 }
132 else {
133 mode = 3;
134 }
135 switch(mode) {
136 case 0:
137 mb_mode = MB_MODE_NONE;
138 break;
139 case 1:
140 mb_mode = MB_MODE_RMB;
141 break;
142 case 2:
143 mb_mode = MB_MODE_WMB;
144 break;
145 case 3:
146 mb_mode = MB_MODE_ALL;
147 break;
148 case 4:
149 mb_mode = MB_MODE_MB;
150 break;
151 case 5:
152 mb_mode = MB_MODE_XMB;
153 break;
154 }
155
156
157 hwloc_topology_init(&topo);
158 hwloc_topology_load(topo);
159
160
161 printf("---------------------------\n");
162 printf("Iterations: %10d\n", max_iters);
163 printf("Mode R MB : %10s\n", (mb_mode & MB_MODE_RMB ? "Enabled" : "Disabled") );
164 printf("Mode W MB : %10s\n", (mb_mode & MB_MODE_WMB ? "Enabled" : "Disabled") );
165 printf("Mode - MB : %10s\n", (mb_mode & MB_MODE_MB ? "Enabled" : "Disabled") );
166 printf("Mode X MB : %10s\n", (mb_mode & MB_MODE_XMB ? "Enabled" : "Disabled") );
167 printf("---------------------------\n");
168
169 bind_me_to(true);
170 handoff.working = false;
171
172
173
174
175 rc = pthread_create(&support_thread, NULL, value_xfer_thread, NULL);
176 if( 0 != rc ) {
177 printf("Error: Failed to create a thread! %d\n", rc);
178 exit(-1);
179 }
180
181
182
183
184 acc_time = 0.0;
185 for(cur_iter = 0; cur_iter < max_iters; ++cur_iter) {
186 perc_current = (cur_iter / ((double)max_iters)) * 100.0;
187 if( perc_current > perc_report_after ) {
188 delta = (acc_time / cur_iter) * 1000000;
189 printf("%6.1f %% complete : Iteration %10d / %10d : %6.1f usec / iter\n",
190 perc_current, cur_iter+1, max_iters, delta);
191 perc_report_after += PERC_INC;
192 }
193
194 start_time = get_ts_gettimeofday();
195
196 val = NULL;
197 handoff.ptr = &val;
198 if( mb_mode & MB_MODE_RMB ) {
199 opal_atomic_rmb();
200 }
201 if( mb_mode & MB_MODE_MB ) {
202 opal_atomic_mb();
203 }
204 handoff.working = true;
205
206
207 while( handoff.working ) {
208 usleep(1);
209 }
210 if( mb_mode & MB_MODE_WMB ) {
211 opal_atomic_wmb();
212 }
213 if( mb_mode & MB_MODE_MB ) {
214 opal_atomic_mb();
215 }
216
217
218 if( NULL == val ) {
219 printf("[%10d / %10d] Error: val = %s\n", cur_iter+1, max_iters,
220 (NULL == val ? "NULL" : "Valid") );
221 exit(-1);
222 }
223 else if( 999 != val->type ) {
224 printf("[%10d / %10d] Error: val->type = %d\n", cur_iter+1, max_iters, val->type);
225 exit(-1);
226 }
227 else if( (cur_iter+1)%MAX_VAL != val->data.int16 ) {
228 printf("[%10d / %10d] Error: val->data.int16 = %d\n", cur_iter+1, max_iters, val->data.int16);
229 exit(-1);
230 }
231
232 stop_time = get_ts_gettimeofday();
233 acc_time += (stop_time - start_time);
234
235
236
237
238
239
240
241 val = NULL;
242 }
243 delta = (acc_time / max_iters) * 1000000;
244
245
246
247
248 time_to_stop = true;
249
250 rc = pthread_join(support_thread, NULL);
251 if( 0 != rc ) {
252 printf("Error: Failed to join a thread! %d\n", rc);
253 exit(-1);
254 }
255
256 hwloc_topology_destroy(topo);
257
258 printf("Success - %6.1f usec / iter\n", delta);
259
260 return 0;
261 }
262
263 void *value_xfer_thread(void *arg) {
264 my_value_t **val = NULL;
265 static int var = 0;
266
267
268 bind_me_to(false);
269
270 while( !time_to_stop ) {
271 if( handoff.working ) {
272
273 if( mb_mode & MB_MODE_WMB ) {
274 opal_atomic_wmb();
275 }
276 if( mb_mode & MB_MODE_MB ) {
277 opal_atomic_mb();
278 }
279
280
281 val = (my_value_t**)handoff.ptr;
282 (*val) = malloc(sizeof(my_value_t));
283 (*val)->type = 999;
284 (*val)->data.int16 = (++var)%MAX_VAL;
285
286
287
288
289 if( mb_mode & MB_MODE_RMB ) {
290 opal_atomic_rmb();
291 }
292 if( mb_mode & MB_MODE_MB ) {
293 opal_atomic_mb();
294 }
295
296 handoff.working = false;
297 }
298 else {
299
300 usleep(1);
301 }
302 }
303 pthread_exit(NULL);
304 }
305
306 void bind_me_to(bool main_thread) {
307 int num_objs;
308 hwloc_cpuset_t set;
309 char *buffer = NULL;
310 hwloc_obj_t obj;
311
312 num_objs = hwloc_get_nbobjs_by_type(topo, OBJ_TYPE);
313
314 if( main_thread ) {
315 obj = hwloc_get_obj_by_type(topo, OBJ_TYPE, 0);
316 }
317 else {
318 obj = hwloc_get_obj_by_type(topo, OBJ_TYPE, num_objs-1);
319 }
320
321 if( obj->type == OBJ_TYPE ) {
322 hwloc_set_cpubind(topo, obj->cpuset, HWLOC_CPUBIND_THREAD);
323 }
324 else {
325 printf("Error: Invalid object\n");
326 exit(-1);
327 }
328
329 set = hwloc_bitmap_alloc();
330 hwloc_get_cpubind(topo, set, HWLOC_CPUBIND_THREAD);
331 hwloc_bitmap_opal_asprintf(&buffer, set);
332 printf("%s : [objs = %d] : cpuset is %s\n", (main_thread ? "Main" : "Peer"), num_objs, buffer);
333 free(buffer);
334 hwloc_bitmap_free(set);
335 }