最小要素のインデックスも必要だとします。これに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] …
}