OpenMP条件严重

问题描述:

首先,请记住,我不是OpenMP的非常频繁的用户......好吗?OpenMP条件严重

现在我们已经过去了,是否有条件的critical
我在这条线并行for循环内特别感兴趣:

(...) 

    #pragma omp critical 
    myMapOfVectors[i].push_back(someNumber); 

(...) 

我想有它critical当且仅当运行这个特定的行具有相同的i(因为我有螺纹一直在经历着 - 如果我错了,请在这里纠正我 - 多个线程推回到相同的vector不是线程安全的并可能导致segfault)。

你需要的是每个索引i有一个lock

// before you parallel region 
std::vector<omp_lock_t> myLocks(myMapOfVectors.size()); 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_init_lock(myLocks+i); 
} 

... 

omp_set_lock(myLocks[i]); 
myMapOfVectors[i].push_back(someNumber); 
omp_unset_lock(myLocks[i]); 

... 

// after your parallel region 
for (size_t i = 0; i < myLocks.size(); ++i) { 
    omp_destroy_lock(myLocks+i); 
} 

临界区是本质上只是一个单一的锁,通过具有针对每个索引的单独临界段多个锁你在本质上的仿。

请记住,锁定速度可能会很慢(特别是如果有碰撞)。如果您可以提前对工作进行分区(即,每个线程在不同的索引集i上工作,或者每个线程都拥有自己的副本myMapOfVectors,以后再合并),您可能会获得更好的性能。

+0

谢谢您的回答!我喜欢你的解决方案,但我希望有一些指令可以帮助我完成繁重的工作。我的意思是,这就是为什么我们有OpenMP,不是吗? :P不是对您的投诉,只是对OpenMP的批评... –

+1

因为编译指示是编译时指示,所以它们不能用于在动态分配的堆对象上进行同步(至少在一般情况下)。如果你实现了自己的栈对象(具有固定的内存分配),你可以使用'#pragma omp atomic'在内部插入元素(插入不会是原子性的,但增加计数)。 – dlasalle