source: benchmark/readyQ/rq_bench.hfa@ 753fb978

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 753fb978 was b7d94ac5, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Last step tools and benchmark

  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <clock.hfa>
2#include <kernel.hfa>
3#include <parseargs.hfa>
4#include <stdio.h>
5#include <stdlib.hfa>
6#include <stats.hfa>
7#include <thread.hfa>
8#include <time.hfa>
9#include <unistd.h>
10
11volatile bool stop = false;
12bool clock_mode;
13double duration = -1;
14unsigned long long stop_count = 0;
15unsigned nprocs = 1;
16unsigned nthreads = 1;
17
18volatile unsigned long long threads_left;
19
20#define thread_loop for(this.count = 0;; this.count++)
21
22#define BENCH_OPT \
23 {'d', "duration", "Duration of the experiments in seconds", duration }, \
24 {'i', "iterations", "Number of iterations of the experiments", stop_count }, \
25 {'t', "nthreads", "Number of threads to use", nthreads }, \
26 {'p', "nprocs", "Number of processors to use", nprocs }
27
28#define BENCH_OPT_PARSE(name) \
29 { \
30 int opt_cnt = sizeof(opt) / sizeof(cfa_option); \
31 char **left; \
32 parse_args( argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, left ); \
33 if(duration > 0 && stop_count > 0) { \
34 fprintf(stderr, "--duration and --iterations cannot be used together\n"); \
35 print_args_usage(argc, argv, opt, opt_cnt, "[OPTIONS]...\n" name, true); \
36 } else if(duration > 0) { \
37 clock_mode = true; \
38 stop_count = 0xFFFFFFFFFFFFFFFF; \
39 printf("Running for %lf seconds\n", duration); \
40 } else if(stop_count > 0) { \
41 clock_mode = false; \
42 printf("Running for %llu iterations\n", stop_count); \
43 } else { \
44 duration = 5; clock_mode = true;\
45 printf("Running for %lf seconds\n", duration); \
46 } \
47 }
48
49struct cluster & bench_cluster;
50
51struct BenchCluster {
52 cluster cl;
53 processor * procs;
54 unsigned nprocs;
55};
56
57void ?{}( BenchCluster & this, unsigned nprocs ) {
58 (this.cl){ "Benchmark Cluster" };
59 &bench_cluster = &this.cl;
60 this.nprocs = nprocs;
61 this.procs = alloc( this.nprocs );
62 for(i; this.nprocs){
63 processor * p = &this.procs[i];
64 (*p){ "Benchmark Processor", this.cl };
65 }
66 #if !defined(__CFA_NO_STATISTICS__)
67 print_stats_at_exit( this.cl, CFA_STATS_READY_Q );
68 #endif
69}
70
71void ^?{}( BenchCluster & this ) {
72 adelete( this.procs );
73 ^(this.cl){};
74}
75
76void wait(const Time & start, bool is_tty) {
77 for() {
78 sleep(100`ms);
79 Time end = timeHiRes();
80 Duration delta = end - start;
81 if(is_tty) {
82 printf(" %.1f\r", delta`ds);
83 fflush(stdout);
84 }
85 if( clock_mode && delta >= duration`s ) {
86 break;
87 }
88 else if( !clock_mode && threads_left == 0 ) {
89 break;
90 }
91 }
92}
93
94struct __attribute__((aligned(128))) bench_sem {
95 struct thread$ * volatile ptr;
96};
97
98static inline {
99 void ?{}(bench_sem & this) {
100 this.ptr = 0p;
101 }
102
103 void ^?{}(bench_sem & this) {}
104
105 bool wait(bench_sem & this) {
106 for() {
107 struct thread$ * expected = this.ptr;
108 if(expected == 1p) {
109 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
110 return false;
111 }
112 }
113 else {
114 /* paranoid */ verify( expected == 0p );
115 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
116 park();
117 return true;
118 }
119 }
120
121 }
122 }
123
124 bool post(bench_sem & this) {
125 for() {
126 struct thread$ * expected = this.ptr;
127 if(expected == 1p) return false;
128 if(expected == 0p) {
129 if(__atomic_compare_exchange_n(&this.ptr, &expected, 1p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
130 return false;
131 }
132 }
133 else {
134 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
135 unpark( expected );
136 return true;
137 }
138 }
139 }
140 }
141}
Note: See TracBrowser for help on using the repository browser.