6

reductionOpenMP 3.1では、次の句を含めることができますmin

double m;
#pragma omp parallel for reduction(min:m)
for (int i=0;i< n; i++){ 
  if (a[i]*2 < m) {
    m = a[i] * 2;
} 
return m;

最小要素のインデックスも必要だとします。reductionこのために句を使用する方法はありますか?nowait別の方法は、とを使用して手動で削減を作成することだと思いますcritical

4

1 に答える 1

5

最小要素のインデックスも必要だとします。これにreduction句を使用する方法はありますか?

残念だけど違う。OpenMPで可能な削減のリストは非常に…小さいです。特に、minおよびmaxは唯一の「高レベル」機能であり、カスタマイズすることはできません。まったく。

私は、OpenMPの削減へのアプローチが好きではないことを認めなければなりません。それは、少しでも拡張できないため、特別な場合にのみ機能するように設計されているからです。確かに、これらは興味深い特殊なケースですが、それでも根本的に悪いアプローチです。

このような操作では、スレッドローカルの結果をスレッドローカル変数に累積し、最後にそれらを組み合わせて、自分で削減を実装する必要があります。

これを行う最も簡単な方法(そして実際にOpenMPが削減を実装する方法に非常に近い)は、各スレッドの要素を含む配列を作成し、を使用omp_get_thread_num()して要素にアクセスすることです。ただし、配列内の要素がキャッシュラインを共有している場合、誤った共有が原因でパフォーマンスが低下することに注意してください。これを軽減するには、配列にパッドを入れます。

struct min_element_t {
    double min_val;
    size_t min_index;
};

size_t const CACHE_LINE_SIZE = 1024; // for example.
std::vector<min_element_t> mins(threadnum * CACHE_LINE_SIZE);

#pragma omp parallel for
for (int i = 0; i < n; ++i) {
    size_t const index = omp_get_thread_num() * CACHE_LINE_SIZE;
    // operate on mins[index] …
}
于 2012-06-28T10:24:34.907 に答える