并行 OpenMP 循环,以继续作为中断替代
Parallel OpenMP loop with continue as a break alternative
我指的是这个问题:Parallel OpenMP loop with break statement
此处建议的代码:
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;
}
}
使用continue
有什么好处?是否比执行以下操作更快:
volatile bool flag=false;
#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{
if(!flag)
{
if(element[i] ...)
{
...
flag=true;
}
}
}
编译后,它们至少在普通情况下是相同的。
如果比较生成的程序集,则两者之间没有区别。我冒昧地添加了 2000 年之前停止的垃圾条件。
正如@Niteya 所指出的,您使用哪一个并不重要,实际上它们是相同的。但是,我想指出,您的代码中存在竞争条件。根据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.
要更正它,您必须使用原子 read/write 操作。所以,你的代码应该是这样的:
#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;
}
}
}
我指的是这个问题:Parallel OpenMP loop with break statement
此处建议的代码:
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;
}
}
使用continue
有什么好处?是否比执行以下操作更快:
volatile bool flag=false;
#pragma omp parallel for shared(flag)
for(int i=0; i<=100000; ++i)
{
if(!flag)
{
if(element[i] ...)
{
...
flag=true;
}
}
}
编译后,它们至少在普通情况下是相同的。
如果比较生成的程序集,则两者之间没有区别。我冒昧地添加了 2000 年之前停止的垃圾条件。
正如@Niteya 所指出的,您使用哪一个并不重要,实际上它们是相同的。但是,我想指出,您的代码中存在竞争条件。根据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.
要更正它,您必须使用原子 read/write 操作。所以,你的代码应该是这样的:
#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;
}
}
}