Я новичок в OpenMP и пытаюсь разобраться в проблеме сбора данных из потоков. Я изучаю пример применения OpenMP по методу Монте-Карло (квадрат круга вписан в квадрат). Я понял, как работает следующий код:
unsigned pointsInside = 0;
#pragma omp parallel for num_threads(threadNum) shared(threadNum) reduction(+: pointsInside)
for (unsigned i = 0; i < threadNum; i++) { ... }
Я прав, что изначально pointsInside
является переменной, но OpenMP представляет ее как массив, а затем мантра reduction(+: pointsInside)
суммирует элементы "массива" "?
Но главный вопрос - как собрать информацию непосредственно в массив или вектор? Я попытался объявить массив или вектор и предоставить указатель или адрес в OpenMP через shared
и собрать информацию для каждого потока по соответствующему индексу. Но работает медленнее, чем с переменной и reduction
. Такой подход с вектором или массивом нужен мне для моего текущего проекта. Большое спасибо!
UPD: Когда я сказал выше, что «он работает медленнее», я имел в виду сравнение двух реализаций метода Монте-Карло: 1) через shared
и вектора / массив и 2) через скалярную переменную и reduction
. Первый случай быстрее. Мое предположение и вопрос об этом ниже.
Я хотел бы перефразировать мой вопрос более четко. Я создаю вектор / массив и предоставляю его в OpenMP через shared
. Я хочу собрать данные для каждого потока по соответствующему индексу в векторе / массиве. При таком подходе мне не нужна синхронизация доступа к вектору / массиву. Правда ли, что OpenMP разрешает синхронизацию по умолчанию, когда я использую shared
. Если это так, то как это отключить. Или, может быть, существуют другие подходы. Если это не так, то как правильно разделить вектор / массив на параллельную часть без синхронизации доступа.
Я хотел бы применить эту технику для моего проекта, где я хочу отсортировать различные перестановки в параллельная часть, собрать каждую перестановку и скалярный результат для нее за пределами параллельной части. Затем отсортируйте результаты и выберите лучший.