使用 continue 作为中断替代方案的并行 OpenMP 循环

发布于 2025-01-13 07:51:06 字数 739 浏览 1 评论 0原文

我指的是这个问题:带有break语句的并行OpenMP循环

代码这里建议:

volatile bool flag=false;

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{    
    if(flag) continue;
    if(element[i] ...)
    {
          ...
          flag=true;
    }
}

使用继续有什么优点?它比执行以下操作更快吗:

volatile bool flag=false;

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{    
    if(!flag)
    {
        if(element[i] ...)
        {
              ...
              flag=true;
        }
    }
}

I'm referring to this question: Parallel OpenMP loop with break statement

The code suggested here:

volatile bool flag=false;

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{    
    if(flag) continue;
    if(element[i] ...)
    {
          ...
          flag=true;
    }
}

What are the advantages of using continue? Is it faster than doing the following:

volatile bool flag=false;

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{    
    if(!flag)
    {
        if(element[i] ...)
        {
              ...
              flag=true;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羁〃客ぐ 2025-01-20 07:51:06

编译后,至少对于普通情况,它们是相同的。

不继续

与Continue

如果您比较生成的程序集,则两者之间没有区别。我冒昧地添加了一个2000年之前停止的垃圾条件。

After compilation, they are identical at least for the trivial case.

Without continue

With Continue

If you compare the resulting assembly there is no difference between the two. I have taken the liberty of adding a junk condition of halting before 2000.

乙白 2025-01-20 07:51:06

正如@Niteya 所指出的,您使用哪一个并不重要,实际上它们是相同的。不过,我想指出的是,您的代码中存在竞争条件。根据 OpenMP 内存模型

如果至少一个线程从内存单元读取并且至少一个
线程在不同步的情况下写入同一内​​存单元,(...),
然后就会发生数据竞争。如果发生数据争用,则结果
程序未指定

要纠正它,您必须使用原子读/写操作。所以,你的代码应该是这样的:

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{        
    bool tmp_flag;
    #pragma omp atomic read acquire
    tmp_flag=flag;
    if(!tmp_flag)
    {
        if(element[i]  == 2000)
        {
            #pragma omp atomic write release
            flag=true;
        }
    }
}

As pointed our by @Niteya it does not really matter which one you use, practically they are the same. I would like to point out, however, that you have a race condition in your code. According to OpenMP memory model:

if at least one thread reads from a memory unit and at least one
thread writes without synchronization to that same memory unit,(...),
then a data race occurs. If a data race occurs then the result of the
program is unspecified
.

To correct it you have to use atomic read/write operations. So, your code should be something like this:

#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{        
    bool tmp_flag;
    #pragma omp atomic read acquire
    tmp_flag=flag;
    if(!tmp_flag)
    {
        if(element[i]  == 2000)
        {
            #pragma omp atomic write release
            flag=true;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文