仅当数据竞赛存在与锁定时,OpenMP关键部分



我的问题与此相似:如何在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]);
}

最新更新