我的问题与这个有点相似:How to use lock in OpenMP? 从某种意义上说,他们的回答有点回答了我的问题,但还不够好。
我正在尝试在 OpenMP 中(从头开始)实现一个简单的工作窃取调度程序。
假设我有一个对象数组,比如 int。我有多个线程将按特定顺序操作此数组的条目。我想确保没有两个线程试图同时访问数组的同一个元素。但是,我允许线程访问同一个元素,只要访问不是同时进行的。此外,我允许线程同时访问数组,只要每个线程希望在此期间访问数组的不同条目即可。我可以使用关键部分,如下所示:
int array[1000];
#pragma omp parallel
{
bool flag = true;
while(flag){
int x = rand()%1000;
#pragma omp critical
{
array[x] = some_function(array[x]);
if (some_condition(array[x])){
flag = false;
}
}
}
}
这段代码创建了一些线程,这些线程随机访问和操作数组的条目,直到出现终止线程的停止条件。这段代码工作正常,因为关键部分确保没有两个线程会同时写入数组(以防它们生成相同的 x 值)。然而,如果在某个时候两个线程没有碰巧生成相同的 x 值,则临界区是冗余的,因为它们没有访问相同的条目。有没有一种方法可以使线程在且仅当它生成的 x 的值与当前也在使用 x 的线程相同时才会停止?现在,这段代码效率低下,而且基本上是串行的,即使每个线程恰好生成不同的 x 值。我想让它们只有在发生碰撞时才会停止。
也许我正在寻找的是锁,但我不确定。关键部分不是去这里的正确方法吗?
最佳答案
我的意思是这样的:
#include <stdlib.h>
#include <omp.h>
int main()
{
int array[1000];
omp_lock_t locks[1000];
for (int i = 0; i < 1000; i++)
omp_init_lock(&locks[i]);
#pragma omp parallel
{
bool flag = true;
while(flag){
int x = rand()%1000;
omp_set_lock(&locks[x]);
array[x] = some_function(array[x]);
if (some_condition(array[x])){
flag = false;
}
omp_unset_lock(&locks[x]);
}
}
for (int i = 0; i < 1000; i++)
omp_destroy_lock(&locks[i]);
}
关于c++ - 仅当存在数据竞争与锁定时才使用 OpenMP 临界区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49500249/