source: doc/theses/thierry_delisle_PhD/code/processor_list_fast.cpp@ b2a37b0

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since b2a37b0 was b2a37b0, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Initial drafts in C++ of the CFA scheduler

  • Property mode set to 100644
File size: 3.5 KB
Line 
1#include "processor_list.hpp"
2
3#include <array>
4#include <iomanip>
5#include <iostream>
6#include <locale>
7#include <string>
8#include <thread>
9
10#include "utils.hpp"
11
12unsigned num() {
13 return 0x1000000;
14}
15
16//-------------------
17
18struct processor {
19 unsigned id;
20};
21void run(unsigned nthread, double duration, unsigned writes) {
22 assert(writes < 100);
23
24 // List being tested
25 processor_list list = {};
26
27 // Barrier for synchronization
28 barrier_t barrier(nthread + 1);
29
30 // Data to check everything is OK
31 size_t write_committed = 0ul;
32 std::atomic_size_t lock_cnt_write = { 0ul };
33 std::atomic_size_t lock_cnt_read = { 0ul };
34
35 // Flag to signal termination
36 std::atomic_bool done = { false };
37
38 std::thread * threads[nthread];
39 unsigned i = 1;
40 for(auto & t : threads) {
41 t = new std::thread([&done, &list, &barrier, &write_committed, &lock_cnt_write, &lock_cnt_read, writes](unsigned tid) {
42 Random rand(tid + rdtscl());
43 processor proc;
44 proc.id = list.doregister(&proc);
45 size_t writes_cnt = 0;
46 size_t reads_cnt = 0;
47
48 affinity(tid);
49
50 barrier.wait(tid);
51
52 while(__builtin_expect(!done, true)) {
53 if ((rand.next() % 100) < writes) {
54 auto n = list.write_lock();
55 write_committed++;
56 writes_cnt++;
57 assert(writes_cnt < -2ul);
58 list.write_unlock(n);
59 }
60 else {
61 list.read_lock(proc.id);
62 reads_cnt++;
63 assert(reads_cnt < -2ul);
64 list.read_unlock(proc.id);
65 }
66 }
67
68 barrier.wait(tid);
69
70 auto p = list.unregister(proc.id);
71 assert(&proc == p);
72 lock_cnt_write += writes_cnt;
73 lock_cnt_read += reads_cnt;
74 }, i++);
75 }
76
77 auto before = Clock::now();
78 barrier.wait(0);
79
80 while(true) {
81 usleep(1000);
82 auto now = Clock::now();
83 duration_t durr = now - before;
84 if( durr.count() > duration ) {
85 done = true;
86 break;
87 }
88 }
89
90 barrier.wait(0);
91 auto after = Clock::now();
92 duration_t durr = after - before;
93 duration = durr.count();
94
95 for(auto t : threads) {
96 t->join();
97 delete t;
98 }
99
100 assert(write_committed == lock_cnt_write);
101
102 size_t ops_sec = size_t(double(lock_cnt_read + lock_cnt_write) / duration);
103 size_t ops_thread = ops_sec / nthread;
104 double dur_nano = duration_cast<std::nano>(1.0);
105
106 std::cout << "Duration : " << duration << "s\n";
107 std::cout << "Total ops : " << (lock_cnt_read + lock_cnt_write) << "(" << lock_cnt_read << "r, " << lock_cnt_write << "w)\n";
108 std::cout << "Ops/sec : " << ops_sec << "\n";
109 std::cout << "Ops/sec/thread: " << ops_thread << "\n";
110 std::cout << "ns/Op : " << ( dur_nano / ops_thread )<< "\n";
111}
112
113void usage(char * argv[]) {
114 std::cerr << argv[0] << ": [DURATION (FLOAT:SEC)] [NTHREADS] [%WRITES]" << std::endl;;
115 std::exit(1);
116}
117
118int main(int argc, char * argv[]) {
119
120 double duration = 5.0;
121 unsigned nthreads = 2;
122 unsigned writes = 0;
123
124 std::cout.imbue(std::locale(""));
125
126 switch (argc)
127 {
128 case 4:
129 writes = std::stoul(argv[3]);
130 if( writes >= 100 ) {
131 std::cerr << "Writes must be valid percentage, was " << argv[3] << "(" << writes << ")" << std::endl;
132 usage(argv);
133 }
134 [[fallthrough]];
135 case 3:
136 nthreads = std::stoul(argv[2]);
137 [[fallthrough]];
138 case 2:
139 duration = std::stod(argv[1]);
140 if( duration <= 0.0 ) {
141 std::cerr << "Duration must be positive, was " << argv[1] << "(" << duration << ")" << std::endl;
142 usage(argv);
143 }
144 [[fallthrough]];
145 case 1:
146 break;
147 default:
148 usage(argv);
149 break;
150 }
151
152 check_cache_line_size();
153
154 std::cout << "Running " << nthreads << " threads for " << duration << " seconds with " << writes << "% writes" << std::endl;
155 run(nthreads, duration, writes);
156
157 return 0;
158}
Note: See TracBrowser for help on using the repository browser.