1/**
2 * \file
3 * \brief BOMP barrier synchronization microbenchmark
4 */
5
6/*
7 * Copyright (c) 2007, 2008, 2009, 2010, ETH Zurich.
8 * All rights reserved.
9 *
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
13 */
14
15#include <stdbool.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <stdint.h>
19#include <omp.h>
20#include <assert.h>
21#include <barrelfish/barrelfish.h>
22#include <trace/trace.h>
23#include <trace_definitions/trace_defs.h>
24
25#define PERIOD          2500000000UL
26#define ITERATIONS	10
27#define STACK_SIZE      (64 * 1024)
28
29struct workcnt {
30  uint64_t	cnt;
31} __attribute__ ((aligned (64)));
32
33int main(int argc, char *argv[])
34{
35  static struct workcnt workcnt[32];
36  static struct workcnt exittime[ITERATIONS];
37  int nthreads;
38  int iterations = 0;
39  uint64_t last;
40
41  /* uint64_t last = rdtsc(); */
42  /* while(rdtsc() < last + PERIOD) { */
43  /*     thread_yield(); */
44  /* } */
45
46  if(argc == 2) {
47      nthreads = atoi(argv[1]);
48      bomp_bomp_init(nthreads);
49      omp_set_num_threads(nthreads);
50  } else {
51      assert(!"Specify number of threads");
52  }
53
54#if CONFIG_TRACE
55    errval_t err = trace_control(TRACE_EVENT(TRACE_SUBSYS_BOMP,
56                                             TRACE_EVENT_BOMP_START, 0),
57                                 TRACE_EVENT(TRACE_SUBSYS_BOMP,
58                                             TRACE_EVENT_BOMP_STOP, 0), 0);
59    assert(err_is_ok(err));
60
61    trace_event(TRACE_SUBSYS_BOMP, TRACE_EVENT_BOMP_START, 0);
62#endif
63
64    /* bomp_synchronize(); */
65    last = rdtsc();
66
67  for(int iter = 0;; iter = (iter + 1) % ITERATIONS) {
68  // Do some work
69#pragma omp parallel
70    for(uint64_t i = 0;; i++) {
71#pragma omp barrier
72      workcnt[omp_get_thread_num()].cnt++;
73
74#pragma omp master
75      if(rdtsc() >= last + PERIOD) {
76#if CONFIG_TRACE
77          trace_event(TRACE_SUBSYS_BOMP, TRACE_EVENT_BOMP_STOP, 0);
78
79          char *buf = malloc(4096*4096);
80          trace_dump(buf, 4096*4096, NULL);
81          printf("%s\n", buf);
82          abort();
83#endif
84
85          printf("%s, %lu: threads %d (%s), progress ", argv[0], rdtsc(), omp_get_num_threads(), omp_get_dynamic() ? "dynamic" : "static");
86          for(int n = 0; n < 32; n++) {
87              printf("%lu ", workcnt[n].cnt);
88          }
89          printf("\n");
90          last += PERIOD;
91          iterations++;
92          if(iterations == 25) {
93              printf("client done\n");
94              abort();
95          }
96
97          if(exittime[iter].cnt == 0) {
98              exittime[iter].cnt = i + 3;
99              exittime[(iter + ITERATIONS - 2) % ITERATIONS].cnt = 0;
100          }
101      }
102
103      if(exittime[iter].cnt != 0 && exittime[iter].cnt == i) {
104          break;
105      }
106    }
107  }
108}
109