c++ - 仅当存在数据竞争与锁定时才使用 OpenMP 临界区?

标签 c++ openmp

我的问题与这个有点相似: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/

相关文章:

c++ - 使用 gcc 插件插入全局变量声明

c++ - 使用 lambda 捕获类后没有合适的复制构造函数

c++ - MPI 与 OpenMP 的性能比较

c++ - OpenMP:深度优先搜索的好策略

gcc - 针对 openmp 的静态链接

c++ - 在位图上并发腐 eclipse 或膨胀

c++做while循环与用户输入

c++ - Qt的编译过程

memory - MPI Fortran 代码 : how to share data on node via openMP?

c++ - VOID 是指 'nothing' 还是 'anything'