void run(ureg threadIndex) { u32 x = X; u32 y = Y; while ((g_random[threadIndex].next32() & 0x7f) != 0) { // Random delay } switch (threadIndex) { case 0: // We store 2 because Junction maps reserve 1 for the default Redirect value. // The default can be overridden, but this is easier. m_map.assign(x, (void*) 2); break; case 1: m_map.assign(y, (void*) 2); break; case 2: m_r1 = (uptr) m_map.get(x); m_r2 = (uptr) m_map.get(y); break; case 3: m_r3 = (uptr) m_map.get(y); m_r4 = (uptr) m_map.get(x); break; } }
void initialPopulate() { TURF_ASSERT(m_addIndex == m_removeIndex); MapAdapter::Map *map = m_shared.map; for (ureg i = 0; i < m_shared.numKeysPerThread; i++) { u32 key = m_addIndex * Prime; map->insert(key, (void*) (key & ~uptr(3))); if (++m_addIndex == m_rangeHi) m_addIndex = m_rangeLo; } }
void run() { MapAdapter::Map *map = m_shared.map; turf::CPUTimer::Converter converter; Delay delay(m_shared.delayFactor); Stats stats; ureg lookupIndex = m_rangeLo; ureg remaining = m_shared.itersPerChunk; if (m_threadIndex == 0) m_shared.spinKicker.kick(m_shared.numThreads - 1); else { remaining = ~u32(0); m_shared.spinKicker.waitForKick(); } // --------- turf::CPUTimer::Point start = turf::CPUTimer::get(); for (; remaining > 0; remaining--) { // Add delay.delay(stats.workUnitsDone); if (m_shared.doneFlag.load(turf::Relaxed)) break; u32 key = m_addIndex * Prime; if (key >= 2) { map->insert(key, (void*) uptr(key)); stats.mapOpsDone++; } if (++m_addIndex == m_rangeHi) m_addIndex = m_rangeLo; // Lookup if (s32(lookupIndex - m_removeIndex) < 0) lookupIndex = m_removeIndex; for (ureg l = 0; l < m_shared.readsPerWrite; l++) { delay.delay(stats.workUnitsDone); if (m_shared.doneFlag.load(turf::Relaxed)) break; key = lookupIndex * Prime; if (key >= 2) { volatile void* value = map->get(key); TURF_UNUSED(value); stats.mapOpsDone++; } if (++lookupIndex == m_rangeHi) lookupIndex = m_rangeLo; if (lookupIndex == m_addIndex) lookupIndex = m_removeIndex; } // Remove delay.delay(stats.workUnitsDone); if (m_shared.doneFlag.load(turf::Relaxed)) break; key = m_removeIndex * Prime; if (key >= 2) { map->erase(key); stats.mapOpsDone++; } if (++m_removeIndex == m_rangeHi) m_removeIndex = m_rangeLo; // Lookup if (s32(lookupIndex - m_removeIndex) < 0) lookupIndex = m_removeIndex; for (ureg l = 0; l < m_shared.readsPerWrite; l++) { delay.delay(stats.workUnitsDone); if (m_shared.doneFlag.load(turf::Relaxed)) break; key = lookupIndex * Prime; if (key >= 2) { volatile void* value = map->get(key); TURF_UNUSED(value); stats.mapOpsDone++; } if (++lookupIndex == m_rangeHi) lookupIndex = m_rangeLo; if (lookupIndex == m_addIndex) lookupIndex = m_removeIndex; } } if (m_threadIndex == 0) m_shared.doneFlag.store(1, turf::Relaxed); m_threadCtx.update(); turf::CPUTimer::Point end = turf::CPUTimer::get(); // --------- stats.duration = converter.toSeconds(end - start); m_stats = stats; }