void operator() ( int id ) const { uintptr_t randomRange = id + MinThread; uintptr_t *curHits = new uintptr_t[randomRange] #if TEST_TOTAL_SEQUENCE , *totalHits = new uintptr_t[randomRange] #endif ; double expectedProbability = 1./randomRange; // Loop through different seeds for ( uintptr_t i = 0; i < NumSeeds; ++i ) { // Seed value mimics the one used by the TBB task scheduler void* seed = (char*)&curHits + i * 16; tbb::internal::FastRandom random( seed ); // According to Section 3.2.1.2 of Volume 2 of Knuth's Art of Computer Programming // the following conditions must be hold for m=2^32: ASSERT((random.c&1)!=0, "c is relatively prime to m"); ASSERT((random.a-1)%4==0, "a-1 is a multiple of p, for every prime p dividing m." " And a-1 is a multiple of 4, if m is a multiple of 4"); memset( curHits, 0, randomRange * sizeof(uintptr_t) ); #if TEST_TOTAL_SEQUENCE memset( totalHits, 0, randomRange * sizeof(uintptr_t) ); #endif const uintptr_t seriesLen = randomRange * SeriesBaseLen, experimentLen = NumSeries * seriesLen; uintptr_t *curSeries = new uintptr_t[seriesLen], // circular buffer randsGenerated = 0; // Initialize statistics while ( randsGenerated < seriesLen ) { uintptr_t idx = random.get() % randomRange; ++curHits[idx]; #if TEST_TOTAL_SEQUENCE ++totalHits[idx]; #endif curSeries[randsGenerated++] = idx; } while ( randsGenerated < experimentLen ) { for ( uintptr_t j = 0; j < randomRange; ++j ) { CheckProbability( double(curHits[j])/seriesLen, expectedProbability, j, randomRange, seed ); #if TEST_TOTAL_SEQUENCE CheckProbability( double(totalHits[j])/randsGenerated, expectedProbability, j, randomRange, seed ); #endif } --curHits[curSeries[randsGenerated % seriesLen]]; int idx = random.get() % randomRange; ++curHits[idx]; #if TEST_TOTAL_SEQUENCE ++totalHits[idx]; #endif curSeries[randsGenerated++ % seriesLen] = idx; } delete [] curSeries; } delete [] curHits; #if TEST_TOTAL_SEQUENCE delete [] totalHits; #endif }
void operator() ( int id ) const { uintptr_t randomRange = id + MinThread; uintptr_t *curHits = new uintptr_t[randomRange] #if TEST_TOTAL_SEQUENCE , *totalHits = new uintptr_t[randomRange] #endif ; double expectedProbability = 1./randomRange; // Loop through different seeds for ( uintptr_t i = 0; i < NumSeeds; ++i ) { // Seed value is selected in two ways, the first of which mimics // the one used by the TBB task scheduler void* seed = i % 2 ? (char*)&curHits + i * 16 : (void*)(i * 8); tbb::internal::FastRandom random( (unsigned)(uintptr_t)seed ); memset( curHits, 0, randomRange * sizeof(uintptr_t) ); #if TEST_TOTAL_SEQUENCE memset( totalHits, 0, randomRange * sizeof(uintptr_t) ); #endif const uintptr_t seriesLen = randomRange * SeriesBaseLen, experimentLen = NumSeries * seriesLen; uintptr_t *curSeries = new uintptr_t[seriesLen], // circular buffer randsGenerated = 0; // Initialize statistics while ( randsGenerated < seriesLen ) { uintptr_t idx = random.get() % randomRange; ++curHits[idx]; #if TEST_TOTAL_SEQUENCE ++totalHits[idx]; #endif curSeries[randsGenerated++] = idx; } while ( randsGenerated < experimentLen ) { for ( uintptr_t j = 0; j < randomRange; ++j ) { CheckProbability( double(curHits[j])/seriesLen, expectedProbability, j, randomRange ); #if TEST_TOTAL_SEQUENCE CheckProbability( double(totalHits[j])/randsGenerated, expectedProbability, j, randomRange ); #endif } --curHits[curSeries[randsGenerated % seriesLen]]; int idx = random.get() % randomRange; ++curHits[idx]; #if TEST_TOTAL_SEQUENCE ++totalHits[idx]; #endif curSeries[randsGenerated++ % seriesLen] = idx; } delete [] curSeries; } delete [] curHits; #if TEST_TOTAL_SEQUENCE delete [] totalHits; #endif }