我的问题与此问题有些类似: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值。我想这样做,只有在发生碰撞时它们才会失速。
也许我正在寻找的是锁,但我不确定。关键部分不是正确的方式去这里吗?
答案 0 :(得分:1)
我的意思是这样的:
#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]);
}