Просмотр исходного кода

Replace locking mutex with per-thread storage

Ivan Savenko 8 месяцев назад
Родитель
Сommit
70cc9f7bb7
1 измененных файлов с 11 добавлено и 25 удалено
  1. 11 25
      AI/Nullkiller/Pathfinding/AINodeStorage.cpp

+ 11 - 25
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<int3> data(committedTiles.begin(), committedTiles.end());
 
-	if(data.size() > 100)
-	{
-		boost::mutex resultMutex;
-
-		std::shuffle(data.begin(), data.end(), randomEngine);
+	int maxConcurrency = tbb::this_task_arena::max_concurrency();
+	std::vector<std::vector<CGPathNode *>> results(maxConcurrency);
 
-		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);
+	logAi->trace("Caculating hero chain for %d items", data.size());
 
-				task.flushResult(heroChain);
-			}
-		});
-	}
-	else
+	tbb::parallel_for(tbb::blocked_range<size_t>(0, data.size()), [&](const tbb::blocked_range<size_t>& r)
 	{
-		auto r = tbb::blocked_range<size_t>(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();