1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-17 20:58:07 +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);
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)
{ {
boost::mutex resultMutex;
std::shuffle(data.begin(), data.end(), randomEngine);
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);
task.execute(r);
{
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); HeroChainCalculationTask task(*this, data, chainMask, heroChainTurn);
int ourThread = tbb::this_task_arena::current_thread_index();
task.execute(r); 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(); committedTiles.clear();