Предположим, мне также нужен индекс минимального элемента; есть ли способ использовать предложение сокращения для этого?
К сожалению, нет. список возможных сокращений в 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] …
}
Я думаю, вы имели в виду 'omp_get_num_threads'? – user1071136
@ user1071136 Нет, я имею в виду 'omp_get_thread_num'. Мы хотим * index *, а не общее число. А что касается 'threadnum', это местозаполнитель. Вы не можете использовать 'omp_get_num_threads' здесь, так как вы не находитесь в параллельном регионе. Вместо этого вы должны фактически передать 'numthread' как число потоков в следующем параллельном предложении. –
+1 для обозначения ложного обмена. Тем не менее, предложения OpenMP для сокращения были разработаны для повышения эффективности и простоты реализации, а не для экстенсибили. –