如何在 OpenMP 中使用锁定?

How to use lock in OpenMP?

提问人:MainID 提问时间:3/7/2010 最后编辑:nbroMainID 更新时间:7/19/2021 访问量:69433

问:

我有两段 C++ 代码在 2 个不同的内核上运行。它们都写入同一个文件。

如何使用 OpenMP 并确保没有崩溃?

C++ 锁定 OpenMP 关键部分

评论


答:

67赞 user257111 3/8/2010 #1

您需要 / 函数: https://hpc.llnl.gov/tuts/openMP/#OMP_SET_LOCKOMP_SET_LOCKOMP_UNSET_LOCK

基本上:

omp_lock_t writelock;

omp_init_lock(&writelock);

#pragma omp parallel for
for ( i = 0; i < x; i++ )
{
    // some stuff
   omp_set_lock(&writelock);
    // one thread at a time stuff
    omp_unset_lock(&writelock);
    // some stuff
}

omp_destroy_lock(&writelock);

大多数锁定例程(如 pthreads 信号量和 sysv 信号量)都适用于这种逻辑,尽管特定的 API 调用不同。

19赞 adamax 5/6/2011 #2
#pragma omp critical
{
    // write to file here
}
40赞 Chris A. 11/6/2012 #3

为了后来者的利益,使用是另一种选择。您甚至可以创建命名的关键部分。critical

例如:

#include <omp.h>

void myParallelFunction()
{
    #pragma omp parallel for
    for(int i=0;i<1000;++i)
    {

        // some expensive work 

        #pragma omp critical LogUpdate
        {
            // critical section where you update file        
        }

        // other work

        #pragma omp critical LogUpdate
        {
            // critical section where you update file      
        }
    }
} 

编辑:Victor Eijkhout发起的评论中有一个很好的主题。总结和释义:简而言之,锁定代码段。在更复杂的示例中,这可能有点矫枉过正,在这些示例中,您要做的就是锁定特定的数据项。在这两种方法之间做出选择之前,了解这一点很重要。critical

评论

9赞 Victor Eijkhout 7/30/2014
Critical 锁定代码段。如果您有数千次迭代,并且只想确保没有两个线程同时执行相同的迭代,这不是一个好主意。使用临界意味着只有一个线程执行任何迭代。命名关键部分稍微缓解了这个问题,但锁更灵活,因为它们锁定的是数据元素,而不是代码片段。
1赞 rph 5/23/2018
@VictorEijkhout 对不起,我不明白这个解决方案与@user257111有何不同。对我来说,用 lock 和 unlock 替换会导致此示例中的代码完全相同,不是吗?#pragma omp critical
0赞 Victor Eijkhout 5/24/2018
@rkioji 最初的问题从未指定需要独占执行的代码是什么,因此很难确定这里适合什么。以数据库为例。使用锁,您可以锁定数据库中的单个项目,以确保没有两个进程同时更新它:锁保护特定的数据项。另一方面,如果在更新周围放置一个关键部分,则确保没有两个进程可以同时执行更新语句,无论它们更新了什么。因此,就数据库而言,关键部分是矫枉过正。(已达到 StackOverflow 限制。
0赞 rph 5/24/2018
@VictorEijkhout我同意你的看法。在某些情况下,锁定数据听起来更有效。我想说的是,在此答案中给出的示例中,使用或锁定/解锁会导致相同的性能。omp critical
1赞 Chris A. 5/25/2018
这些都是我在写这篇文章时没有意识到的要点。我已经编辑了答案来总结。