以下簡單代碼不會給出gcc 4.7.0的預期結果。這是正確的還是一個錯誤?omp減少和lambda函數
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;
}
這將返回零:從lambda函數中減少c
未完成。順便說一句,我期望得到的結果是由串行功能
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;
}
以下實施方式中得到預期的結果(在兩種情況下,代碼定義做減少變量的增量移動到並行區域)返回
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;
}
的事實是count_err()
給出了不同的結果的編譯器錯誤或正確的嗎?
不要嘗試將OpenMP與高級構造混合在一起,它肯定會失敗:OpenMP對於這一點太簡單了。它與語言整合的設計(但不是真的)是根本上有缺陷的。改爲手動減少。 –
@KonradRudolph,lambdas是現有更詳細的C++功能的語法糖,因此它們使用函數編譯爲相同的代碼。 OpenMP僅爲#pragma部分中的代碼創建線程函數,並映射私有或共享變量。編譯器找出它並不是一件大事。另外它們都在編譯器中實現。 –
@ lucas1024沒錯,這不是什麼大不了的事。更可惜的是它不能可靠地工作。 OpenMP甚至在最基本的C++構造塊上扼流(例如,嘗試通過'return'退出臨界區)。 –