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

ast-experimental
Last change on this file since 2cb8bf71 was 0da7181, checked in by caparsons <caparson@…>, 16 months 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.