Changes in / [42cd451e:f4ec4a90]
- Location:
- doc/theses/thierry_delisle_PhD/code
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp
r42cd451e rf4ec4a90 8 8 #define SNZM 4 9 9 #define BIAS 5 10 #define BACK 6 11 #define BACKBIAS 7 10 12 11 13 #ifndef VARIANT … … 18 20 19 21 #include <cmath> 22 #include <functional> 20 23 #include <memory> 21 24 #include <mutex> 25 #include <thread> 22 26 #include <type_traits> 23 27 … … 26 30 #include "links.hpp" 27 31 #include "snzi.hpp" 32 #include "snzi-packed.hpp" 28 33 #include "snzm.hpp" 29 34 … … 68 73 "RELAXED: SNZI + DISCOVERED MASK", 69 74 "RELAXED: SNZI + MASK", 70 "RELAXED: SNZI + LOCAL BIAS" 75 "RELAXED: SNZI + LOCAL BIAS", 76 "RELAXED: SNZI + REVERSE RNG", 77 "RELAXED: SNZI + LOCAL BIAS + REVERSE RNG" 71 78 }; 72 79 return names[VARIANT]; … … 76 83 : numLists(numThreads * numQueues) 77 84 , lists(new intrusive_queue_t<node_t>[numLists]) 78 #if VARIANT == SNZI || VARIANT == B IAS85 #if VARIANT == SNZI || VARIANT == BACK 79 86 , snzi( std::log2( numLists / (2 * numQueues) ), 2 ) 87 #elif VARIANT == BIAS || VARIANT == BACKBIAS 88 #ifdef SNZI_PACKED 89 , snzi( std::ceil( std::log2(numLists) ) ) 90 #else 91 , snzi( std::log2( numLists / (2 * numQueues) ), 2 ) 92 #endif 80 93 #elif VARIANT == SNZM || VARIANT == DISCOVER 81 94 , snzm( numLists ) … … 96 109 while(true) { 97 110 // Pick a random list 98 #if VARIANT == BIAS 99 unsigned r = tls.rng.next(); 100 unsigned i; 101 if(0 == (r & 0xF)) { 102 i = r >> 4; 103 } else { 104 i = tls.my_queue + ((r >> 4) % 4); 105 tls.pick.push.local++; 106 } 107 i %= numLists; 108 #else 109 unsigned i = tls.rng.next() % numLists; 110 #endif 111 unsigned i = idx_from_r(tls.rng1.next(), VARIANT == BIAS || VARIANT == BACKBIAS); 111 112 112 113 #ifndef NO_STATS … … 117 118 if( !lists[i].lock.try_lock() ) continue; 118 119 119 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS120 #if VARIANT == VANILLA || VARIANT == BITMASK 120 121 __attribute__((unused)) int num = numNonEmpty; 121 122 #endif … … 131 132 #elif VARIANT == SNZI || VARIANT == BIAS 132 133 snzi.arrive(i); 134 #elif VARIANT == BACK || VARIANT == BACKBIAS 135 snzi.arrive(i); 136 tls.rng2.set_raw_state( tls.rng1.get_raw_state()); 133 137 #elif VARIANT == SNZM 134 138 snzm.arrive(i); … … 145 149 #endif 146 150 } 147 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS151 #if VARIANT == VANILLA || VARIANT == BITMASK 148 152 assert(numNonEmpty <= (int)numLists); 149 153 #endif … … 154 158 #ifndef NO_STATS 155 159 tls.pick.push.success++; 156 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS160 #if VARIANT == VANILLA || VARIANT == BITMASK 157 161 tls.empty.push.value += num; 158 162 tls.empty.push.count += 1; … … 171 175 { 172 176 // Pick first list totally randomly 173 i = tls.rng .next() % numLists;177 i = tls.rng1.next() % numLists; 174 178 175 179 // Pick the other according to the bitmask 176 unsigned r = tls.rng .next();180 unsigned r = tls.rng1.next(); 177 181 178 182 size_t mask = tls.mask.load(std::memory_order_relaxed); … … 197 201 while(snzi.query()) { 198 202 // Pick two lists at random 199 int i = tls.rng.next() % numLists; 200 // int j = tls.rng.next() % numLists; 203 int i = tls.rng1.next() % numLists; 204 int j = tls.rng1.next() % numLists; 205 206 if(auto node = try_pop(i, j)) return node; 207 } 208 209 #elif VARIANT == BACK 210 while(snzi.query()) { 211 // Pick two lists at random 212 int i = tls.rng2.prev() % numLists; 213 int j = tls.rng2.prev() % numLists; 214 215 if(auto node = try_pop(i, j)) return node; 216 } 217 218 #elif VARIANT == BACKBIAS 219 while(snzi.query()) { 220 // Pick two lists at random 221 int i = idx_from_r(tls.rng2.prev(), true); 222 int j = idx_from_r(tls.rng2.prev(), true); 201 223 202 224 if(auto node = try_pop(i, j)) return node; … … 206 228 while(snzi.query()) { 207 229 // Pick two lists at random 208 unsigned ri = tls.rng .next();230 unsigned ri = tls.rng1.next(); 209 231 unsigned i; 210 unsigned j = tls.rng .next();232 unsigned j = tls.rng1.next(); 211 233 if(0 == (ri & 0xF)) { 212 234 i = (ri >> 4) % numLists; … … 228 250 { 229 251 // Pick two random number 230 unsigned ri = tls.rng .next();231 unsigned rj = tls.rng .next();252 unsigned ri = tls.rng1.next(); 253 unsigned rj = tls.rng1.next(); 232 254 233 255 // Pick two nodes from it … … 270 292 while(snzm.query()) { 271 293 // Pick two lists at random 272 int i = tls.rng .next() % numLists;273 int j = tls.rng .next() % numLists;294 int i = tls.rng1.next() % numLists; 295 int j = tls.rng1.next() % numLists; 274 296 275 297 if(auto node = try_pop(i, j)) return node; … … 285 307 unsigned num = ((numLists - 1) >> 6) + 1; 286 308 287 unsigned ri = tls.rng .next();288 unsigned rj = tls.rng .next();309 unsigned ri = tls.rng1.next(); 310 unsigned rj = tls.rng1.next(); 289 311 290 312 unsigned wdxi = (ri >> 6u) % num; … … 314 336 while(numNonEmpty != 0) { 315 337 // Pick two lists at random 316 int i = tls.rng .next() % numLists;317 int j = tls.rng .next() % numLists;338 int i = tls.rng1.next() % numLists; 339 int j = tls.rng1.next() % numLists; 318 340 319 341 if(auto node = try_pop(i, j)) return node; … … 348 370 if( !list.lock.try_lock() ) return nullptr; 349 371 350 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS372 #if VARIANT == VANILLA || VARIANT == BITMASK 351 373 __attribute__((unused)) int num = numNonEmpty; 352 374 #endif … … 371 393 __attribute__((unused)) bool ret = btr(tls.mask, bit); 372 394 snzm.depart(w); 373 #elif VARIANT == SNZI || VARIANT == BIAS 395 #elif VARIANT == SNZI || VARIANT == BIAS || VARIANT == BACK || VARIANT == BACKBIAS 374 396 snzi.depart(w); 375 397 #elif VARIANT == SNZM … … 390 412 // Unlock and return 391 413 list.lock.unlock(); 392 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS414 #if VARIANT == VANILLA || VARIANT == BITMASK 393 415 assert(numNonEmpty >= 0); 394 416 #endif 395 417 #ifndef NO_STATS 396 418 tls.pick.pop.success++; 397 #if VARIANT != SNZM && VARIANT != SNZI && VARIANT != DISCOVER && VARIANT != BIAS419 #if VARIANT == VANILLA || VARIANT == BITMASK 398 420 tls.empty.pop.value += num; 399 421 tls.empty.pop.count += 1; … … 403 425 } 404 426 427 inline unsigned idx_from_r(unsigned r, bool bias) { 428 unsigned i; 429 if(bias) { 430 if(0 == (r & 0x3F)) { 431 i = r >> 6; 432 } else { 433 i = tls.my_queue + ((r >> 6) % 4); 434 tls.pick.push.local++; 435 } 436 } else { 437 i = r; 438 } 439 return i % numLists; 440 } 405 441 406 442 public: 407 443 408 444 static __attribute__((aligned(128))) thread_local struct TLS { 409 Random rng = { int(rdtscl()) }; 445 Random rng1 = { unsigned(std::hash<std::thread::id>{}(std::this_thread::get_id()) ^ rdtscl()) }; 446 Random rng2 = { unsigned(std::hash<std::thread::id>{}(std::this_thread::get_id()) ^ rdtscl()) }; 410 447 unsigned my_queue = (ticket++) * 4; 411 448 pick_stat pick; … … 418 455 __attribute__((aligned(64))) std::unique_ptr<intrusive_queue_t<node_t> []> lists; 419 456 private: 420 #if VARIANT == SNZI || VARIANT == B IAS457 #if VARIANT == SNZI || VARIANT == BACK 421 458 snzi_t snzi; 459 #elif VARIANT == BIAS || VARIANT == BACKBIAS 460 #ifdef SNZI_PACKED 461 snzip_t snzi; 462 #else 463 snzi_t snzi; 464 #endif 422 465 #elif VARIANT == SNZM || VARIANT == DISCOVER 423 466 snzm_t snzm; -
doc/theses/thierry_delisle_PhD/code/snzi.hpp
r42cd451e rf4ec4a90 14 14 15 15 void arrive(int idx) { 16 idx >>= 2; 16 17 idx %= mask; 17 18 nodes[idx].arrive(); … … 19 20 20 21 void depart(int idx) { 22 idx >>= 2; 21 23 idx %= mask; 22 24 nodes[idx].depart(); … … 82 84 if( x.cnt == val_t::Half ) { 83 85 /* paranoid */ assert(parent); 84 parent->arrive(); 86 if(undoArr == 2) { 87 undoArr--; 88 } else { 89 parent->arrive(); 90 } 85 91 if( !value.cas(x, 1, x.ver) ) { 86 92 undoArr = undoArr + 1; … … 151 157 { 152 158 int width = std::pow(base, depth); 153 std::cout << "SNZI: " << depth << "x" << width << "(" << mask - 1 << ") " << std::endl;159 std::cout << "SNZI: " << depth << "x" << width << "(" << mask - 1 << ") " << (sizeof(snzi_t::node) * (root + 1)) << " bytes" << std::endl; 154 160 for(int i = 0; i < root; i++) { 155 nodes[i].parent = &nodes[(i / base) + width ]; 161 std::cout << i << " -> " << (i / base) + width << std::endl; 162 nodes[i].parent = &nodes[(i / base) + width]; 156 163 } 157 164 } -
doc/theses/thierry_delisle_PhD/code/utils.hpp
r42cd451e rf4ec4a90 35 35 }; 36 36 37 // class Random { 38 // private: 39 // unsigned int seed; 40 // public: 41 // Random(int seed) { 42 // this->seed = seed; 43 // } 44 45 // /** returns pseudorandom x satisfying 0 <= x < n. **/ 46 // unsigned int next() { 47 // seed ^= seed << 6; 48 // seed ^= seed >> 21; 49 // seed ^= seed << 7; 50 // return seed; 51 // } 52 // }; 53 54 constexpr uint64_t extendedEuclidY(uint64_t a, uint64_t b); 55 constexpr uint64_t extendedEuclidX(uint64_t a, uint64_t b){ 56 return (b==0) ? 1 : extendedEuclidY(b, a - b * (a / b)); 57 } 58 constexpr uint64_t extendedEuclidY(uint64_t a, uint64_t b){ 59 return (b==0) ? 0 : extendedEuclidX(b, a - b * (a / b)) - (a / b) * extendedEuclidY(b, a - b * (a / b)); 60 } 61 37 62 class Random { 38 63 private: 39 unsigned int seed; 64 uint64_t x; 65 66 static constexpr const uint64_t M = 1ul << 48ul; 67 static constexpr const uint64_t A = 25214903917; 68 static constexpr const uint64_t C = 11; 69 static constexpr const uint64_t D = 16; 70 40 71 public: 41 Random(int seed) { 42 this->seed = seed; 72 static constexpr const uint64_t m = M; 73 static constexpr const uint64_t a = A; 74 static constexpr const uint64_t c = C; 75 static constexpr const uint64_t d = D; 76 static constexpr const uint64_t ai = extendedEuclidX(A, M); 77 public: 78 Random(unsigned int seed) { 79 this->x = seed * a; 43 80 } 44 81 45 82 /** returns pseudorandom x satisfying 0 <= x < n. **/ 46 83 unsigned int next() { 47 seed ^= seed << 6; 48 seed ^= seed >> 21; 49 seed ^= seed << 7; 50 return seed; 51 } 84 //nextx = (a * x + c) % m; 85 x = (A * x + C) & (M - 1); 86 return x >> D; 87 } 88 unsigned int prev() { 89 //prevx = (ainverse * (x - c)) mod m 90 unsigned int r = x >> D; 91 x = ai * (x - C) & (M - 1); 92 return r; 93 } 94 95 void set_raw_state(uint64_t _x) { 96 this->x = _x; 97 } 98 99 uint64_t get_raw_state() { 100 return this->x; 101 } 52 102 }; 53 103
Note: See TracChangeset
for help on using the changeset viewer.