- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp
rb232745 rf0c3120 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;
Note: See TracChangeset
for help on using the changeset viewer.