From 70cc9f7bb762a76fb66d9b15c937925ee32dfdb6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 3 Feb 2025 17:13:48 +0000 Subject: [PATCH] Replace locking mutex with per-thread storage --- AI/Nullkiller/Pathfinding/AINodeStorage.cpp | 40 +++++++-------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp index a40fbd7d2..a7826b73f 100644 --- a/AI/Nullkiller/Pathfinding/AINodeStorage.cpp +++ b/AI/Nullkiller/Pathfinding/AINodeStorage.cpp @@ -582,42 +582,28 @@ public: bool AINodeStorage::calculateHeroChain() { - std::random_device randomDevice; - std::mt19937 randomEngine(randomDevice()); - heroChainPass = EHeroChainPass::CHAIN; heroChain.clear(); std::vector data(committedTiles.begin(), committedTiles.end()); - if(data.size() > 100) + int maxConcurrency = tbb::this_task_arena::max_concurrency(); + std::vector> results(maxConcurrency); + + logAi->trace("Caculating hero chain for %d items", data.size()); + + tbb::parallel_for(tbb::blocked_range(0, data.size()), [&](const tbb::blocked_range& r) { - boost::mutex resultMutex; - - std::shuffle(data.begin(), data.end(), randomEngine); - - tbb::parallel_for(tbb::blocked_range(0, data.size()), [&](const tbb::blocked_range& r) - { - //auto r = blocked_range(0, data.size()); - HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn); - - task.execute(r); - - { - boost::lock_guard resultLock(resultMutex); - - task.flushResult(heroChain); - } - }); - } - else - { - auto r = tbb::blocked_range(0, data.size()); HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn); + int ourThread = tbb::this_task_arena::current_thread_index(); task.execute(r); - task.flushResult(heroChain); - } + task.flushResult(results.at(ourThread)); + }); + + // FIXME: potentially non-deterministic behavior due to parallel_for + for (const auto & result : results) + vstd::concatenate(heroChain, result); committedTiles.clear();