Wal*_*ter 2 c++ lambda openmp c++11
以下简单代码没有给出gcc 4.7.0的预期结果.这是正确的还是错误的?
unsigned count_err(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
// enables to reuse the lambda later (not in this simple example)
auto f = [&] (unsigned i) { if(i&mask) ++c; };
#pragma omp parallel for reduction(+:c)
for(unsigned i=0; i<num.size(); ++i)
f(num[i]);
return c;
}
Run Code Online (Sandbox Code Playgroud)
这返回零:c没有完成lambda函数的减少.顺便说一句,我期望结果是串行函数返回的结果
unsigned count_ser(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
auto f = [&] (unsigned i) { if(i&mask) ++c; };
std::for_each(num.begin(),num.end(),f);
return c;
}
Run Code Online (Sandbox Code Playgroud)
以下实现给出了预期的结果(在这两种情况下,执行减少变量增量的代码定义被移动到并行区域)
unsigned count_ok1(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
auto f = [&] (unsigned i) -> bool { return i&mask; };
#pragma omp parallel for reduction(+:c)
for(unsigned i=0; i<num.size(); ++i)
if(f(num[i])) ++c;
return c;
}
unsigned count_ok2(std::vector<unsigned> const&num, unsigned mask)
{
unsigned c=0;
#pragma omp parallel reduction(+:c)
{
auto f = [&] (unsigned i) { if(i&mask) ++c; };
#pragma omp for
for(unsigned i=0; i<num.size(); ++i)
f(num[i]);
}
return c;
}
Run Code Online (Sandbox Code Playgroud)
事实是,count_err()给出了不同的结果编译器错误或正确吗?
我认为这不是编译器错误.这是我的解释.我想在你的第一个例子中,lambdas持有对全局c变量的引用.c我们进入for循环时创建了线程本地副本.因此线程正在递增相同的全局变量(没有任何同步).当我们退出循环时,线程局部副本c(全部等于零,因为lambdas不知道它们)总结为0.该count_ok2版本有效,因为lambdas持有对本地c副本的引用.
| 归档时间: |
|
| 查看次数: |
1423 次 |
| 最近记录: |