bool clusterExists(std::string& infoSet) {
bool exists {false};
#pragma omp critical
exists = mInfoMap.find(infoSet) != mInfoMap.end();
return exists;
}
InfoSet* get(std::string& infoSet, const int& numActs, Env::History& actions) {
if (numActs > 0 && mCreateNotExists && !clusterExists(infoSet)) {
#pragma omp critical
{
mInfoMap.insert({infoSet, new InfoSet {numActs}});
for (auto& a : actions) {
mInfoMap[infoSet]->insertActStr(Env::ActToStr(std::get<1>(a)), std::get<2>(a));
}
}
}
return mInfoMap[infoSet];
}
我认为问题出在“插入”上。 问题是因为地图是一个“STL容器”并且它需要锁?
您没有提供足够的代码,所以我不知道 OMP 并行部分是什么样子,但我猜您的
critical
,一旦您让它工作,将完全否定任何并行性能。
使代码变得非常快的一种方法是为每个线程提供自己的映射版本,进行完全独立/并行插入,并最终协调本地映射。最优雅的方法是在地图上定义
operator+
,并将平行部分设为 reduction(+:mymap)
。
这将以几乎完美的加速运行,但请注意,这将导致线程数量的多倍内存需求。如果您的映射非常大——因此不太可能发生插入冲突——请使用锁而不是关键部分。