source: doc/theses/colby_parsons_MMAth/benchmarks/mutex_stmt/cpp/rand.cc@ e10714a

ADT ast-experimental
Last change on this file since e10714a was 0da7181, checked in by caparsons <caparson@…>, 3 years ago

added randomized lock ordering bench for mutexstmt

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include <cstdio>
2#include <mutex>
3#include <thread>
4#include <chrono>
5#include <stdlib.h>
6#include "cppLock.hpp"
7
8#include "../bench.h"
9
10cpp_test_spinlock LOCKS;
11cpp_test_spinlock ** lock_arr;
12
13inline void locks( size_t * arr ) {
14 if (num_locks == 2) {
15 std::scoped_lock lock( *lock_arr[arr[0]], *lock_arr[arr[1]] );
16 } else if (num_locks == 4) {
17 std::scoped_lock lock( *lock_arr[arr[0]], *lock_arr[arr[1]], *lock_arr[arr[2]], *lock_arr[arr[3]] );
18 } else if (num_locks == 8) {
19 std::scoped_lock lock( *lock_arr[arr[0]], *lock_arr[arr[1]], *lock_arr[arr[2]], *lock_arr[arr[3]], *lock_arr[arr[4]], *lock_arr[arr[5]], *lock_arr[arr[6]], *lock_arr[arr[7]] );
20 }
21}
22
23bool done = false;
24uint64_t total = 0;
25size_t num_gen = 100; // number of rand orderings per thd
26size_t ** rand_arrs;
27
28// generate repeatable orderings for each experiment
29void gen_orders() {
30 rand_arrs = new size_t *[threads];
31 for ( int i = 0; i < threads; i++ )
32 rand_arrs[i] = new size_t[ num_locks * num_gen ];
33
34 size_t work_arr[num_locks];
35
36 for ( int i = 0; i < num_locks; i++ )
37 work_arr[i] = i;
38
39 size_t curr_idx;
40 for ( int i = 0; i < threads; i++ ) {
41 state = i;
42 curr_idx = 0;
43 for ( int j = 0; j < num_gen; j++ ) {
44 for ( size_t k = num_locks; k > 0; k-- ) {
45 size_t rand_idx = next_int() % k; // choose one of remaining elems in work_arr
46 rand_arrs[i][curr_idx] = work_arr[rand_idx];
47 curr_idx++;
48
49 // swap chosen elem to end so it isn't picked again
50 size_t temp = work_arr[rand_idx];
51 work_arr[rand_idx] = work_arr[k - 1];
52 work_arr[k - 1] = temp;
53 }
54 }
55
56 }
57}
58
59void thread_main( int id ) {
60 size_t * my_arr = rand_arrs[id];
61 uint64_t count = 0;
62 while (true) {
63 locks( my_arr + (count % num_gen) * num_locks );
64 count++;
65 if (done) break;
66 }
67 __atomic_add_fetch(&total, count, __ATOMIC_SEQ_CST);
68}
69
70int main( int argc, char * argv[] ) {
71 BENCH_START()
72 if ( num_locks == -1 ) { printf("must pass # of locks to program!\n"); exit( EXIT_FAILURE ); }
73
74 lock_arr = new cpp_test_spinlock *[ num_locks ];
75
76 if (num_locks >= 2) {
77 lock_arr[0] = &l1; lock_arr[1] = &l2;
78 }
79 if (num_locks >= 4) {
80 lock_arr[2] = &l3; lock_arr[3] = &l4;
81 }
82 if (num_locks == 8) {
83 lock_arr[4] = &l5; lock_arr[5] = &l6; lock_arr[6] = &l7; lock_arr[7] = &l8;
84 }
85
86 gen_orders();
87
88 std::thread myThreads[threads];
89 for (int i = 0; i < threads; i++) {
90 myThreads[i] = std::thread(thread_main, i); // move constructed
91 }
92
93 std::this_thread::sleep_for (std::chrono::seconds(10));
94 done = true;
95
96 for (int i = 0; i < threads; i++) {
97 myThreads[i].join();
98 }
99
100 for ( int i = 0; i < threads; i++ )
101 delete[] rand_arrs[i];
102 delete[] rand_arrs;
103 delete[] lock_arr;
104
105 printf( "%lu\n", total );
106}
107
108// Local Variables: //
109// tab-width: 4 //
110// End: //
Note: See TracBrowser for help on using the repository browser.