は、以下のコードを見てみましょう:ラムダ関数型クリープ
tbb::blocked_range<int> range(0, a.rows);
uint64_t positive = tbb::parallel_reduce(range, 0, // <- initial value
[&](const tbb::blocked_range<int>& r, uint64_t v)->uint64_t {
for (int y = r.begin(); y < r.end(); ++y) {
auto rA = a[y], rB = b[y];
for (int x = 0; x < a.cols; ++x) {
auto A = rA[x], B = rB[x];
for (int l = y; l < a.rows; ++l) {
auto rAA = a[l], rBB = b[l];
for (int m = x; m < a.cols; ++m) {
if (l == y && m == x)
continue;
auto AA = rAA[m], BB = rBB[m];
if ((A == AA) && (B == BB))
v++; // <- value is changed
if ((A != AA) && (B != BB))
v++; // <- value is changed
}
}
}
}
return v;
}, [](uint64_t first, uint64_t second)->uint64_t {
std::cerr << first << ' + ' << second; // <- wrong values occur
return first+second;
}
);
は、これは、初期値が初期値に基づいて、各並列計算で、その後は0である並列減らす操作で、私たちをカウントアップする(最初のラムダ関数のローカル変数v
)。 2番目のラムダ関数は、並列作業者からの結果を集計します。
興味深いことに、このコードはではなく、が正常に動作します。 2番目のラムダ関数の出力には、整数のオーバーフローによる膨大な数値が表示されます。
uint64_t positive = tbb::parallel_reduce(range, (uint64_t)0, // <- initial value
は今、私は疑問に思う:と二行目の交換時
コードが正常に動作します。最初のラムダ(uint64_t v
)の定義はこのキャストを強制しないでしょうし、uint64_tで動作するはずの関数はどうやってintで動作するのでしょうか?
コンパイラはGCC 6です。
'0'は 'int' ... – Jarod42
確実なことです。しかし、引数 'v'は' uint64_t'です。 – ypnos