1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-19 21:10:12 +02:00

Replace locking mutex with per-thread storage

This commit is contained in:
Ivan Savenko 2025-02-03 17:13:48 +00:00
parent e113622dc3
commit 70cc9f7bb7

View File

@ -582,42 +582,28 @@ public:
bool AINodeStorage::calculateHeroChain() bool AINodeStorage::calculateHeroChain()
{ {
std::random_device randomDevice;
std::mt19937 randomEngine(randomDevice());
heroChainPass = EHeroChainPass::CHAIN; heroChainPass = EHeroChainPass::CHAIN;
heroChain.clear(); heroChain.clear();
std::vector<int3> data(committedTiles.begin(), committedTiles.end()); std::vector<int3> data(committedTiles.begin(), committedTiles.end());
if(data.size() > 100) int maxConcurrency = tbb::this_task_arena::max_concurrency();
{ std::vector<std::vector<CGPathNode *>> results(maxConcurrency);
boost::mutex resultMutex;
std::shuffle(data.begin(), data.end(), randomEngine); logAi->trace("Caculating hero chain for %d items", data.size());
tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size()), [&](const tbb::blocked_range<size_t>& r) tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size()), [&](const tbb::blocked_range<size_t>& r)
{ {
//auto r = blocked_range<size_t>(0, data.size());
HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn); HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn);
int ourThread = tbb::this_task_arena::current_thread_index();
task.execute(r); task.execute(r);
task.flushResult(results.at(ourThread));
{
boost::lock_guard<boost::mutex> resultLock(resultMutex);
task.flushResult(heroChain);
}
}); });
}
else
{
auto r = tbb::blocked_range<size_t>(0, data.size());
HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn);
task.execute(r); // FIXME: potentially non-deterministic behavior due to parallel_for
task.flushResult(heroChain); for (const auto & result : results)
} vstd::concatenate(heroChain, result);
committedTiles.clear(); committedTiles.clear();