Changeset 6c58850 for doc/theses/mike_brooks_MMath/benchmarks/list/driver.c
- Timestamp:
- Aug 12, 2025, 12:44:35 AM (2 months ago)
- Branches:
- master
- Children:
- 7f995d70
- Parents:
- 81e1984b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/mike_brooks_MMath/benchmarks/list/driver.c
r81e1984b r6c58850 3 3 #include <stdlib.h> 4 4 #include <string.h> 5 #include <stdint.h> 6 #include <assert.h> 5 7 6 8 #ifdef DISABLE_OBSERVATION … … 11 13 #endif 12 14 13 #ifdef TINY_USER_ITEMS 14 #define UDATA_T char 15 #define UDATA_LEN 1 16 #define UDATA_USE_POS 0 17 #else 18 #define UDATA_T int 19 #define UDATA_LEN 64 20 #define UDATA_USE_POS 17 15 #ifdef HUGE_USER_ITEMS 16 #define UDATA_T float 17 #define UDATA_LEN 17 21 18 #endif 22 19 23 typedef struct B_UserItem 20 // canonical insertion order means the order of traversing B_UserItem.{succ|pred}_pos references 21 // outer v middle action: as at (just after) inserting or (just before) removing the element in question... 22 // - outer-action node: one that is at the front or back of the list 23 // - middle-action node: otherwise 24 // outer action is 25 // - typical/default: middle action happens only when InterleaveFrac > 0, and only on this fraction 26 // - logically first: a prefix of items, in canonical insertion order, gets outer action; a suffix gets middle action 27 // regardless of interleaving, canonical insertion order is the same as linked-list element order in the final built-up state, up to polarity 28 // nontrivial interleaving makes the time oder of insertion/removal _operation_invocations_ different from canonical 29 typedef enum InterleaveAction { OuterActn = 0, InnerActn = 1 } InterleaveAction; 30 enum { N_INTERLEAVE_ACTION = 2 } ; 31 32 typedef 33 struct __attribute__(( aligned(64) )) B_UserItem 24 34 BFX_EXTRUSION_DECL(B_UserItem) 25 35 { 26 36 BFX_INTRUSION(B_UserItem) 27 // BFX_LISTED_ELEM_T(B_UserItem) selfListed; 28 UDATA_T userdata[ UDATA_LEN ]; 37 #ifndef DISABLE_SHUFFLING_INDIRECTION 38 size_t succ_pos; 39 size_t pred_pos; 40 #endif 41 size_t self_ord; 42 #ifndef DISABLE_INTERLEAVING 43 InterleaveAction later_flip; 44 #endif 45 #ifndef DISABLE_ITERS 46 BFX_LISTED_ELEM_T(struct B_UserItem) selfListed; 47 #endif 48 #ifdef HUGE_USER_ITEMS 49 UDATA_T udata[UDATA_T] __attribute__((unused)); 50 #endif 29 51 } 30 52 B_UserItem; … … 52 74 static B_UserItem *ui = NULL; 53 75 54 static BFX_LISTED_ELEM_T(B_UserItem) *listedItems = NULL;55 76 static BFX_LISTED_ELEM_T(B_UserItem) observedItem; 56 77 57 78 static BFX_LIST_HEAD_T(B_UserItem) lst; 79 80 B_UserItem * seekUi( size_t i ) { 81 #ifdef DISABLE_SHUFFLING_INDIRECTION 82 return & ui[i]; 83 #else 84 B_UserItem * cur = & ui[0]; 85 for (; i > 0; i--) cur = & ui[ cur->succ_pos ]; 86 return cur; 87 #endif 88 } 58 89 59 90 #ifdef DISABLE_OBSERVATION 60 91 MAYBE_EXTERN_C ( 61 void bobs_seek( unsigned int i) {}92 void bobs_seek(size_t i) {} 62 93 void bobs_moveNext() {} 63 94 void bobs_movePrev() {} 64 intbobs_hasCurrent() { return 0; }95 bool bobs_hasCurrent() { return 0; } 65 96 void * bobs_getCurrentLoc() { return NULL; } 66 int bobs_getCurrentVal() { return 0; }97 size_t bobs_getCurrentVal() { return 0; } 67 98 // enum bobs_op_movement_t bobs_op_movement = OP_MOVEMENT; 68 99 // enum bobs_op_polarity_t bobs_op_polarity = OP_POLARITY; … … 74 105 75 106 volatile size_t bobs_ops_completed = 0; 76 volatile unsigned int bobs_prog_inserting = 0;77 volatile unsigned int bobs_prog_removing = 0;78 volatile unsigned int bobs_prog_removing_end = 0;79 volatile unsigned int bobs_prog_rollover_flag = 0;107 volatile size_t bobs_prog_inserting = 0; 108 volatile size_t bobs_prog_removing = 0; 109 volatile size_t bobs_prog_removing_end = 0; 110 volatile size_t bobs_prog_rollover_flag = 0; 80 111 // bobs_prog_rem_pos (defined after BOP_REMPROGEND_IS_REMNO_BASED) 81 112 82 void bobs_seek(unsigned int i) { 83 observedItem = listedItems[i]; 113 void bobs_seek(size_t i) { 114 #ifndef DISABLE_ITERS 115 observedItem = seekUi(i)->selfListed; 116 #endif 84 117 } 85 118 … … 92 125 } 93 126 94 intbobs_hasCurrent() {127 bool bobs_hasCurrent() { 95 128 return BFX_IS_VALID_POS(B_UserItem, lst, observedItem); 96 129 } … … 99 132 return BFX_DEREF_POS(B_UserItem, lst, observedItem); 100 133 } 101 int bobs_getCurrentVal() {134 size_t bobs_getCurrentVal() { 102 135 B_UserItem * curUI = BFX_DEREF_POS(B_UserItem, lst, observedItem); 103 return curUI-> userdata[ UDATA_USE_POS ];136 return curUI->self_ord; 104 137 } 105 138 … … 112 145 #ifndef DISABLE_OBSERVATION 113 146 114 // Remove progress end ( number) is based (upon) remove-number147 // Remove progress end (as in, outer) (number) is based (upon) remove-number 115 148 // True when an OP's REMELEM used remNo to choose which element to remove 116 149 // False otherwise; notably including when REMELEM just bases upon first/last … … 120 153 #endif 121 154 MAYBE_EXTERN_C ( 122 volatile unsigned int const * bobs_prog_rem_pos =155 volatile size_t const * bobs_prog_rem_pos = 123 156 #ifdef DISABLE_INTERLEAVING 124 157 & bobs_prog_removing … … 131 164 #endif // ndef DISABLE_OBSERVATION 132 165 133 unsigned int uDefaultPreemption() {134 return 0;135 }136 137 #ifdef DISABLE_ITERS _AR166 // size_t uDefaultPreemption() { 167 // return 0; 168 // } 169 170 #ifdef DISABLE_ITERS 138 171 // Saves on memory accesses, makes element-oriented removals and observation impossible (instead, they crash) 139 172 static inline BFX_LISTED_ELEM_T(B_UserItem) buhrdice_pass( BFX_LISTED_ELEM_T(B_UserItem) v ) { // prevent eliding, cheaper than volatile … … 144 177 #endif 145 178 179 // begin: copied from https://stackoverflow.com/a/33021408 180 #define IMAX_BITS(m) ((m)/((m)%255+1) / 255%255*8 + 7-86/((m)%255+12)) 181 #define RAND_MAX_WIDTH IMAX_BITS(RAND_MAX) 182 static_assert((RAND_MAX & (RAND_MAX + 1u)) == 0, "RAND_MAX not a Mersenne number"); 183 184 uint64_t rand64(void) { 185 uint64_t r = 0; 186 for (int i = 0; i < 64; i += RAND_MAX_WIDTH) { 187 r <<= RAND_MAX_WIDTH; 188 r ^= (unsigned) rand(); 189 } 190 return r; 191 } 192 // end: copied from https://stackoverflow.com/a/33021408 193 146 194 int main(int argc, const char *argv[]) { 147 195 … … 149 197 // define the outbound dependencies as locals, for compiling into nops 150 198 size_t bobs_ops_completed = 0; 151 unsigned int bobs_prog_inserting = 0;152 unsigned int bobs_prog_removing = 0;153 unsigned int bobs_prog_removing_end = 0;154 unsigned int bobs_prog_rollover_flag = 0;199 size_t bobs_prog_inserting = 0; 200 size_t bobs_prog_removing = 0; 201 size_t bobs_prog_removing_end = 0; 202 size_t bobs_prog_rollover_flag = 0; 155 203 #endif 156 204 … … 158 206 const int static_arg_posns = 6; 159 207 160 unsigned int ExperimentDurSec = DefaultExperimentDurSec;161 unsigned int CheckDonePeriod = DefaultCheckDonePeriod;162 unsigned int NumNodes = DefaultNumNodes;163 size_t 164 unsigned int Seed = DefaultSeed;165 double 208 size_t ExperimentDurSec = DefaultExperimentDurSec; 209 size_t CheckDonePeriod = DefaultCheckDonePeriod; 210 size_t NumNodes = DefaultNumNodes; 211 size_t ExperimentDurOpCount = DefaultExperimentDurOpCount; 212 size_t Seed = DefaultSeed; 213 double InterleaveFrac = DefaultInterleaveFrac; 166 214 167 215 switch (((argc - 1) < static_arg_posns) ? (argc - 1) : static_arg_posns) { … … 189 237 #endif 190 238 191 // Shuffling makes listed items' physical order in memory different from their order within to the list.192 // Affects insertion: next item to insert picked through insertOrdShuf.193 #ifdef DISABLE_SHUFFLING_INDIRECTION194 #define INSERTPOS(insertNum) insertNum195 #else196 // To ensure random memory order of nodes being inserted, do so according to a shuffled ordering of them.197 unsigned int * insertOrdShuf = (unsigned int *) malloc( (size_t)NumNodes * sizeof(unsigned int) );198 if (!insertOrdShuf) {199 printf("malloc request for %zd bytes for insertOrdShuf refused\n", (size_t)NumNodes * (size_t)sizeof(unsigned int));200 return 1;201 }202 // Fill with the ordinals (iota)203 for (int i = 0; i < NumNodes; i++) {204 insertOrdShuf[i] = i;205 }206 // Dummy "Seed" of -1 means skip the shuffle: measure overhead of insertOrdShuf indirection207 if (Seed != -1) {208 // Shuffle209 srand(Seed);210 for (unsigned int i = 0; i < NumNodes; i++) {211 unsigned int nodesRemaining = NumNodes - i;212 unsigned int swapWith = i + rand() % nodesRemaining;213 unsigned int tempValue = insertOrdShuf[swapWith];214 insertOrdShuf[swapWith] = insertOrdShuf[i];215 insertOrdShuf[i] = tempValue;216 }217 }218 #define INSERTPOS(insertNum) insertOrdShuf[insertNum]219 #endif220 221 // Interleaving affects the list position where an element-oriented operation occurs: at an end vs. in the middle.222 // Perterbs the sequence of logical insert/remove numbers presented to the OP cartridge, e.g. from [0 1 2 3 4 5 6]223 // to [3 0 4 1 5 2 6], which is [mid end mid end mid end solo], for a perfect-alternation interleave; except that the224 // end/mid interleave is atually selected randomly.225 #ifdef DISABLE_INTERLEAVING226 #define nextInterleave 0227 #else228 const unsigned int INTRL_KEYLEN = 64;229 unsigned char interleaveKey[INTRL_KEYLEN];230 unsigned char nextInterleavePos = 0;231 {232 unsigned int numOnes = INTRL_KEYLEN * InterleaveFrac;233 unsigned int numZeros = INTRL_KEYLEN - numOnes;234 // generate randomly drawn 0/1235 memset( interleaveKey , 0, numZeros ); // zeros then ones236 memset( interleaveKey+numZeros, 1, numOnes );237 for (unsigned int i = 0; i < 64; i++) { // shuffle it238 unsigned int nodesRemaining = 64 - i;239 unsigned int swapWith = i + rand() % nodesRemaining;240 unsigned char tempValue = interleaveKey[swapWith];241 interleaveKey[swapWith] = interleaveKey[i];242 interleaveKey[i] = tempValue;243 }244 #define nextInterleave (interleaveKey[nextInterleavePos = (nextInterleavePos + 1) % 64])245 }246 {247 unsigned int z = 0, o = 0;248 for ( int i = 0; i < INTRL_KEYLEN; i++ ) {249 if (interleaveKey[i]) o++;250 else z++;251 }252 // printf("Interleaving with %u in middle and %u at end\n", o, z);253 }254 // printf("interleave key begins %016llx\n", *(unsigned long long*)interleaveKey);255 // printf("interleave key begins %016llx\n", *(unsigned long long*)(interleaveKey+8));256 // printf("sample interleave value %d\n", nextInterleave);257 // printf("sample interleave value %d\n", nextInterleave);258 // printf("sample interleave value %d\n", nextInterleave);259 // printf("sample interleave value %d\n", nextInterleave);260 // printf("sample interleave value %d\n", nextInterleave);261 // printf("sample interleave value %d\n", nextInterleave);262 // printf("sample interleave value %d\n", nextInterleave);263 // printf("sample interleave value %d\n", nextInterleave);264 // printf("sample interleave value %d\n", nextInterleave);265 // printf("sample interleave value %d\n", nextInterleave);266 // printf("sample interleave value %d\n", nextInterleave);267 // printf("sample interleave value %d\n", nextInterleave);268 #endif269 270 239 ui = (B_UserItem*) malloc( (size_t)NumNodes * (size_t)sizeof(B_UserItem) ); 271 240 if (!ui) { … … 274 243 } 275 244 memset(ui, 0, (size_t)NumNodes * (size_t)sizeof(B_UserItem)); 276 277 #ifndef DISABLE_ITERS_AR 278 listedItems = (BFX_LISTED_ELEM_T(B_UserItem)*)malloc( (size_t)NumNodes * (size_t)sizeof(BFX_LISTED_ELEM_T(B_UserItem)) ); 279 if (!listedItems) { 280 printf("malloc request for %zd bytes for listedItems refused\n", (size_t)NumNodes * (size_t)sizeof(BFX_LISTED_ELEM_T(B_UserItem))); 281 return 1; 282 } 283 memset(listedItems, 0, (size_t)NumNodes * (size_t)sizeof(BFX_LISTED_ELEM_T(B_UserItem))); 284 #define ITERS_SAVE(i, insertElemExpr) listedItems[i] = (insertElemExpr) 285 #endif 286 287 // Construct and fill with demo data 288 for (unsigned int i = 0; i < NumNodes; i++) { 289 B_UserItem * curUI = & ui[INSERTPOS(i)]; 290 #ifdef __cforall 245 // Construct 246 #ifdef __cforall 247 for (size_t i = 0; i < NumNodes; i++) { 248 B_UserItem * curUI = & ui[i]; 291 249 (*curUI){}; 292 #endif 293 curUI->userdata[ UDATA_USE_POS ] = i; 294 } 250 } 251 #endif 252 253 // Shuffling makes listed items' physical order in memory different from their order within to the list. 254 // Affects insertion: next item to insert picked through insertOrdShuf. 255 #ifdef DISABLE_SHUFFLING_INDIRECTION 256 for ( size_t insertOrdinal = 0; insertOrdinal < NumNodes; insertOrdinal += 1 ) { 257 ui[insertOrdinal].self_ord = insertOrdinal; 258 } 259 #else 260 // To ensure random memory order of nodes being inserted, do so according to a shuffled ordering of them. 261 { 262 // insertOrdShuf is a temporary list of integers; once the order is generated, we'll write its consequence into the elements 263 size_t * insertOrdShuf = (size_t *) malloc( sizeof( size_t ) * NumNodes ); 264 if (!insertOrdShuf) { 265 printf("malloc request for %zd bytes for insertOrdShuf refused\n", (size_t)NumNodes * (size_t)sizeof(size_t)); 266 return 1; 267 } 268 // Fill with the ordinals (iota) 269 for (size_t i = 0; i < NumNodes; i++) { 270 insertOrdShuf[i] = i; 271 } 272 // Dummy "Seed" of -1 means skip the shuffle: measure overhead of shuffling indirection 273 if (Seed != -1) { 274 // Shuffle per https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#Sattolo's_algorithm 275 // Don't want to draw from all permutations, only single-cycle permutations 276 srand(Seed); 277 for (size_t i = NumNodes - 1; i > 0; --i) { 278 size_t j = rand64() % i; // j in [0, i-1] 279 size_t tmp = insertOrdShuf[i]; 280 insertOrdShuf[i] = insertOrdShuf[j]; 281 insertOrdShuf[j] = tmp; 282 } 283 } 284 // take inserOrdShuf as successor-index; write consequences of this traversal into the elements 285 size_t lastPos = 0; 286 size_t curPos = 0; 287 for ( size_t insertOrdinal = 0; insertOrdinal < NumNodes; insertOrdinal += 1 ) { 288 B_UserItem * curItem = & ui[ curPos ]; 289 curItem->succ_pos = insertOrdShuf[ curPos ]; 290 curItem->pred_pos = lastPos; 291 curItem->self_ord = insertOrdinal; 292 lastPos = curPos; 293 curPos = curItem->succ_pos; 294 } 295 assert( curPos == 0 ); // completed sole cycle 296 ui[0].pred_pos = lastPos; 297 free(insertOrdShuf); 298 } 299 #define INSERTPOS(insertNum) insertOrdShuf[insertNum] 300 #endif 301 302 303 /* 304 305 306 307 308 309 TO FIX 310 311 312 313 314 315 clarify self_ord meaning insertion order or physical-adjacency order 316 317 318 319 320 321 322 323 324 325 */ 326 327 328 // Interleaving affects the list position where an element-oriented operation occurs: at an outer vs. inner node. 329 // Perterbs the sequence of logical insert/remove numbers presented to the OP cartridge, e.g. from [0 1 2 3 4 5 6] 330 // to [3 0 4 1 5 2 6], which is [inner outer inner outer inner outer solo], for a perfect-alternation interleave; except that the 331 // outer/inner interleave is atually selected randomly. 332 #ifndef DISABLE_INTERLEAVING 333 // see InterleaveAction comments near top 334 335 size_t numNodesItlv[N_INTERLEAVE_ACTION] = {}; // logically const, complex init 336 337 // 338 // begin: specific to a two-fingered interleave 339 // 340 static_assert( OuterActn == 0 && InnerActn == 1 && N_INTERLEAVE_ACTION == 2 ); 341 342 const size_t iactSplitPos = NumNodes - NumNodes * InterleaveFrac; 343 344 // initialize numNodesItlv 345 numNodesItlv[InnerActn] = (NumNodes-1) * InterleaveFrac; // inner, later: usual outer-inner order revd for data dep 346 numNodesItlv[OuterActn] = (NumNodes-1) - numNodesItlv[InnerActn]; // outer, earlier: ditto 347 assert( (numNodesItlv[InnerActn] + numNodesItlv[OuterActn] == NumNodes - 1) && 348 "The two modes are meant to cover all items but one, which is left for bop_setup/bop_teardown" ); 349 350 B_UserItem * const iactFwdStartItem[N_INTERLEAVE_ACTION] = { seekUi(0), (iactSplitPos == NumNodes) ? NULL : seekUi(iactSplitPos) }; 351 B_UserItem * const iactRevStartItem[N_INTERLEAVE_ACTION] = { seekUi(NumNodes-1), (iactSplitPos == NumNodes) ? NULL : seekUi(NumNodes - iactSplitPos -1) }; 352 353 { 354 // Not all nodes'interleave invalues are random. Need bookending nodes set to specific values. 355 // Last node seen in outer handling 356 // - must refer to inner mode 357 // - is near the split position (middle of list) 358 // - forward outer processing goes first to middle 359 // - reverse outer processing goes last to middle 360 // Last node seen in inner handling 361 // - must refer to outer mode 362 // - is at a leaf (first or last of list) 363 // - forward inner processing goes middle to last 364 // - reverse inner processing goes middle to first 365 // One of these cross references gets navigated, when its mode is the one that finishes first. 366 // (By then, all references "back" into this mode have been used up, so it's a termination condition for the mode that finishes first.) 367 // When the other mode exhausts its stash, the global ternimation condition (handled all non setup/teardown nodes) overrides its cross reference. 368 // Call out these four nodes as special (equal number, 2, referring to each mode); fill the rest randomly. 369 370 assert( InterleaveFrac >= 0.0 && InterleaveFrac <= 1.0 ); 371 // no action required on no-interleave 372 if ( InterleaveFrac > 0.0 ) { 373 374 // assert( ( NumNodes >= 2 * N_INTERLEAVE_ACTION) 375 // && "Don't feel like dealing with interleave edge cases on tiny lists"); 376 377 if ( NumNodes >= 2 * N_INTERLEAVE_ACTION ) { 378 InterleaveAction * interleaveKey = (InterleaveAction *) malloc( sizeof(InterleaveAction) * NumNodes ); 379 380 const size_t iactStartPos [N_INTERLEAVE_ACTION] = { 0, iactSplitPos }; 381 const size_t iactFinshPos [N_INTERLEAVE_ACTION] = { iactSplitPos, NumNodes }; 382 383 // generate randomly drawn ikey values 384 static_assert( 1 && "sorry, not checkable" && "values of InterleaveAction are enumerable" ); 385 for ( unsigned char kk = 0; kk < (unsigned char) N_INTERLEAVE_ACTION; kk++ ) { // fill to the fractions 386 InterleaveAction k = (InterleaveAction) kk; 387 for ( int i = iactStartPos[k]; i < iactFinshPos[k]; i++ ) { 388 interleaveKey[i] = k; 389 } 390 } 391 for (size_t i = 0; i < NumNodes; i++) { // shuffle 392 size_t nodesRemaining = NumNodes - i; 393 size_t swapWith = i + (rand64() % nodesRemaining); 394 InterleaveAction tempValue = interleaveKey[swapWith]; 395 interleaveKey[swapWith] = interleaveKey[i]; 396 interleaveKey[i] = tempValue; 397 } 398 for (size_t i = 0; i < NumNodes; i++) { // record inside items 399 ui[i].later_flip = interleaveKey[i]; 400 } 401 // set bookened positions 402 // FIXME: still incorrect; can't simply overwrite like done here; 403 // need to find an oppositely actioned node to swap with; 404 // as is, 405 // ./perfexp--upp-upp--queue-inslast-remelem 5 100000 37 -1 3 .50 406 // gets one too many outers; 407 // this extra outer reenables the outer cursor at ordinal 18 408 // after the inner cursor already remvoed ordinal 18 409 assert(false && "need to fix bookends"); 410 seekUi( iactStartPos[OuterActn] )->later_flip = OuterActn; 411 seekUi( iactStartPos[InnerActn] )->later_flip = InnerActn; 412 seekUi( iactFinshPos[OuterActn] -1 )->later_flip = InnerActn; 413 seekUi( iactFinshPos[InnerActn] -1 )->later_flip = OuterActn; 414 // 415 // end: specific to a two-fingered interleave 416 // 417 free(interleaveKey); 418 } else { 419 // makefile targets call it, not easy to disable 420 // so just fill as if no interleave 421 for (size_t i = 0; i < NumNodes; i++) { 422 ui[i].later_flip = OuterActn; 423 } 424 } 425 } 426 427 } 428 #endif 429 430 #ifndef DISABLE_ITERS 431 #define ITERS_SAVE(lastInsertedElemPtr, lastInsertedIter) (lastInsertedElemPtr)->selfListed = lastInsertedIter 432 #endif 295 433 296 434 BFX_INIT(B_UserItem, lst); … … 314 452 // Cartridges whose SUT insert/remove actions work on empty lists need not provide special-case ones. 315 453 #ifndef BOP_INIT 316 #define BOP_INIT(lst, ite rs, insNo, item) BOP_INSERT(lst, iters, insNo, item)454 #define BOP_INIT(lst, item) BOP_INSERT(lst, ERROR_REQD_ITER_NOT_PROVIDED, item) 317 455 #endif 318 456 #ifndef BOP_TEARDOWN 319 #define BOP_TEARDOWN(lst , iters, remNo) BOP_REMOVE(lst, iters, remNo)457 #define BOP_TEARDOWN(lst) BOP_REMOVE(lst, ERROR_REQD_ITER_NOT_PROVIDED) 320 458 #endif 459 460 461 size_t privateOpsCompleted = 0; 321 462 322 463 double elapsed_sec = 0; 323 464 clock_t start = clock(); 324 325 const unsigned int numMiddleNodes = (NumNodes-1) * InterleaveFrac;326 const unsigned int numEndNodes = NumNodes - numMiddleNodes - 1;327 328 // printf("Running with %u in the middle and %u at end\n", numMiddleNodes, numEndNodes);329 330 const unsigned int removeBase[] = {0, numEndNodes};331 const unsigned int removeLimit[] = {numEndNodes, numMiddleNodes};332 333 size_t privateOpsCompleted = 0;334 465 335 466 while (elapsed_sec <= (double) ExperimentDurSec && privateOpsCompleted < ExperimentDurOpCount) { 336 for ( int t = 0; t < CheckDonePeriod; t += 1 ) {467 for ( size_t t = 0; t < CheckDonePeriod; t += 1 ) { 337 468 TRACE('a') // insert special first 338 ITERS_SAVE( 0,339 BOP_INIT(lst, listedItems, 0, ui[INSERTPOS(0)]) );469 ITERS_SAVE( &ui[0], 470 BOP_INIT(lst, ui[0]) ); 340 471 TRACE('b') // insert general 341 for ( int privateCurInsert = 1; 472 // Keep lastInserted even on DISABLE_ITERS because it's communication to the remove phase 473 BFX_LISTED_ELEM_T(B_UserItem) lastInserted = BFX_GET_FIRST(B_UserItem, lst); 474 B_UserItem * insertNow = seekUi(1); 475 for ( size_t privateCurInsert = 1; 342 476 (bobs_prog_inserting = privateCurInsert, privateCurInsert < NumNodes); 343 477 privateCurInsert += 1 344 478 ) { 479 assert( insertNow->self_ord == privateCurInsert ); 345 480 TRACE('-') 346 ITERS_SAVE( privateCurInsert,347 BOP_INSERT( lst, l istedItems, privateCurInsert, ui[INSERTPOS(privateCurInsert)]) );481 lastInserted = 482 BOP_INSERT( lst, lastInserted, (*insertNow) ); 348 483 TRACE('+') 484 ITERS_SAVE( insertNow, lastInserted ); 485 #ifdef DISABLE_SHUFFLING_INDIRECTION 486 insertNow++; 487 #else 488 insertNow = & ui[ insertNow->succ_pos ]; 489 #endif 349 490 } 350 491 #ifdef DISABLE_INTERLEAVING 351 492 // interleaving off, simple removes 352 493 // (remove logic of 2b01f8eb0956) 494 #ifndef DISABLE_ITERS 495 BFX_LISTED_ELEM_T(B_UserItem) nextRemoval = BOP_SWITCH_REMDIR ( 496 ui[0].selfListed, // forward starts from first insert 497 lastInserted // backward starts from last insert 498 ); 499 #endif 353 500 TRACE('c') 354 for ( int privateCurRemove = 1;501 for ( size_t privateCurRemove = 1; 355 502 (bobs_prog_removing = privateCurRemove, privateCurRemove < NumNodes); 356 503 privateCurRemove += 1 357 504 ) { 505 #ifdef DISABLE_ITERS 506 #define curRemovalI ERROR_REQD_ITER_NOT_PROVIDED 507 #else 508 BFX_LISTED_ELEM_T(B_UserItem) curRemovalI = nextRemoval; 509 B_UserItem * curRemovalE = BFX_DEREF_POS(B_UserItem, lst, nextRemoval); 510 #ifdef DISABLE_SHUFFLING_INDIRECTION 511 nextRemoval = (BOP_SWITCH_REMDIR( curRemovalE + 1, curRemovalE - 1 ))->selfListed; 512 #else 513 nextRemoval = ui[ curRemovalE->BOP_SWITCH_REMDIR(succ_pos, pred_pos) ].selfListed; 514 #endif 515 #endif 358 516 TRACE('-') 359 BOP_REMOVE( lst, listedItems, privateCurRemove-1);517 BOP_REMOVE( lst, curRemovalI ); 360 518 TRACE('+') 361 519 } … … 363 521 // interleaving on, complex removes 364 522 TRACE('c') // remove general 365 int removeProgress[] = { 0, 0 }; 366 for ( int flip = 0; 367 (bobs_prog_removing = removeProgress[0] + removeProgress[1] + 1, 523 size_t removeProgress [N_INTERLEAVE_ACTION] = { 0, 0 }; 524 #define startItem BOP_SWITCH_REMDIR( iactFwdStartItem, iactRevStartItem ) 525 B_UserItem * removeItem[N_INTERLEAVE_ACTION] = 526 { startItem[OuterActn], startItem[InnerActn] }; 527 for ( InterleaveAction flip = OuterActn 528 ; (bobs_prog_removing = removeProgress[0] + removeProgress[1] + 1, 368 529 bobs_prog_removing_end = removeProgress[0] + 1, 369 flip = nextInterleave, 370 removeProgress[0] < removeLimit[0] && removeProgress[1] < removeLimit[1] ); 371 removeProgress[flip] += 1 530 removeProgress[0] + removeProgress[1] < NumNodes - 1 ) 531 ; 372 532 ) { 533 //printf("--- flip=%d removeProgress[0]=%zd removeProgress[1]=%zd removeItem[flip]->self_ord=%zd\n", flip, removeProgress[0], removeProgress[1], removeItem[flip]->self_ord); 373 534 TRACE('-') 374 BOP_REMOVE( lst, listedItems, removeBase[flip]+removeProgress[flip]);535 BOP_REMOVE( lst, removeItem[flip]->selfListed ); 375 536 TRACE('+') 537 538 InterleaveAction nextFlip = removeItem[flip]->later_flip; 539 removeProgress[flip] += 1; 540 removeItem[flip] = & ui[ removeItem[flip]-> BOP_SWITCH_REMDIR(succ_pos, pred_pos) ]; 541 flip = nextFlip; 376 542 } 377 TRACE('X') // remove imbalanced 378 // most work done under general; it stops when either flip-side's work finishes 379 // now drain any any stragglers so both flip-sides' work finishes 380 for ( int flip = 0; flip < 2; flip ++ ) { 381 for ( ; (bobs_prog_removing = removeProgress[0] + removeProgress[1] + 1, 382 bobs_prog_removing_end = removeProgress[0] + 1, 383 removeProgress[flip] < removeLimit[flip] ) 384 ; removeProgress[flip] += 1 385 ) { 386 TRACE('-') 387 BOP_REMOVE( lst, listedItems, removeBase[flip]+removeProgress[flip] ); 388 TRACE('+') 389 } 390 } 543 544 // for ( InterleaveAction flip = OuterActn; 545 // (bobs_prog_removing = removeProgress[0] + removeProgress[1] + 1, 546 // bobs_prog_removing_end = removeProgress[0] + 1, 547 // removeProgress[0] < numNodesItlv[0] && removeProgress[1] < numNodesItlv[1] ); 548 // ) { 549 // TRACE('-') 550 // BOP_REMOVE( lst, removeItem[flip]->selfListed ); 551 // TRACE('+') 552 553 // InterleaveAction nextFlip = removeItem[flip]->later_flip; 554 // removeProgress[flip] += 1; 555 // removeItem[flip] = & ui[ removeItem[flip]-> BOP_SWITCH_REMDIR(succ_pos, pred_pos) ]; 556 // flip = nextFlip; 557 // } 558 // TRACE('X') // remove imbalanced 559 // // most work done under general; it stops when either flip-side's work finishes 560 // // now drain any any stragglers so both flip-sides' work finishes 561 // for ( InterleaveAction flip = 0; flip < N_INTERLEAVE_ACTION; flip ++ ) { 562 // for ( ; (bobs_prog_removing = removeProgress[0] + removeProgress[1] + 1, 563 // bobs_prog_removing_end = removeProgress[0] + 1, 564 // removeProgress[flip] < numNodesItlv[flip] ) 565 // ; 566 // ) { 567 // //printf("--- flip=%d removeProgress[flip]=%zd numNodesItlv[flip]=%zd removeItem[flip]->self_ord=%zd\n", flip, removeProgress[flip], numNodesItlv[flip], removeItem[flip]->self_ord); 568 // TRACE('-') 569 // BOP_REMOVE( lst, removeItem[flip]->selfListed ); 570 // TRACE('+') 571 572 // removeProgress[flip] += 1; 573 // removeItem[flip] = & ui[ removeItem[flip]-> BOP_SWITCH_REMDIR(succ_pos, pred_pos) ]; 574 // } 575 // } 391 576 #endif // DISABLE_INTERLEAVING 392 577 TRACE('D') // remove special last 393 BOP_TEARDOWN(lst , listedItems, NumNodes-1);578 BOP_TEARDOWN(lst); 394 579 TRACE('d') 395 580 … … 422 607 423 608 free(ui); 424 free(listedItems);425 #ifndef DISABLE_SHUFFLING_INDIRECTION426 free(insertOrdShuf);427 #endif428 609 }
Note:
See TracChangeset
for help on using the changeset viewer.