Есть ли способ «разделить» барьер синхронизации OpenMP?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Есть ли способ «разделить» барьер синхронизации OpenMP?

Сообщение Anonymous »

У меня есть какой-то код, который ранее выглядел как: < /p>

Код: Выделить всё

std::vector data;
do { // May run 100 times or more
prepare();
remaining = compute1(my_data);
remaining -= compute2(my_data);
cleanup(my_data);
} while (remaining > 0);
Where each function prepare(), compute1(), compute2() and cleanup() is somewhat compute intensive and parallelized with big for loops with #pragma omp parallel for schedule(static).
Some benchmarking showed significant time spent synchronizing Потоки, поэтому я подумал о переходе на один параллельный раздел и распределение по данным между потоками. Код будет выглядеть как: < /p>

Код: Выделить всё

std::vector data;
std::atomic remaining;
#pragma omp parallel
{
std::vector my_data;
#pragma for schedule(static)
for (int i = 0; i < data.size(); i++) {
my_data.push_back(data[i]);
}
do { // May run 100 times or more
prepare();
remaining = 0;
remaining += compute1(my_data);
remaining -= compute2(my_data);
cleanup(my_data);
} while (remaining > 0);
}
Конечно, есть некоторые ограничения синхронизации, которые необходимо рассмотреть, первые 3 являются несколько очевидными:
  • Ни один поток не должен выполнять оставшиеся += compute1 () , прежде чем все потоки будут выполнять оставшиеся = 0 В потоках запускаются оставшиеся -= compute2 () инструкция.
  • Ни один поток не должен запустить оставшиеся = 0 Инструкция, прежде чем все потоки протестировали предыдущий оставшиеся> 0 Условие. Compute2 () инструкция.
  • Ни один поток не должен запустить оставшуюся инструкцию += compute1 () Перед тем, как все потоки запускают инструкцию Prepare () .
  • Ни один поток не должен запустить оставшуюся часть -= Compute2 () Перед тем, как все потоки. Вычислить функции).
Ограничение № 6 выглядит просто: стандартный барьер сделает это нормально.
ограничение № 1 также легко удовлетворить: оставшееся = 0 Инструкция должна быть выполнена с #prongma omp opm . Использование барьеров: < /p>

Код: Выделить всё

std::vector data;
std::atomic remaining;
#pragma omp parallel
{
std::vector my_data;
#pragma for schedule(static)
for (int i = 0; i < data.size(); i++) {
my_data.push_back(data[i]);
}
do { // May run 100 times or more
prepare();
#pragma omp barrier
#pragma omp single
remaining = 0;
remaining += compute1(my_data);
#pragma omp barrier
remaining -= compute2(my_data);
cleanup(my_data);
#pragma omp barrier
} while (remaining > 0);
}
< /code>
Когда я сравниваю это, это показывает значительное улучшение по сравнению с предыдущей версией, где каждая функция была независимо параллелизирована. Моя интуиция заключается в том, что каждый поток, имеющий свои собственные данные, улучшает местонахождение данных и скорость попадания локального CPU/Core Cache.
Но я думаю, что есть многие ненужные ограничения. Если бы у меня был способ иметь какой -то «барьерный раздел», который ни один поток не может оставить до того, как все потоки введут его, я мог бы сделать что -то гораздо менее ограниченное. Я мог бы реализовать это с чем-то вроде: < /p>
std::vector data;
std::atomic remaining;
#pragma omp parallel
{
std::vector my_data;
#pragma for schedule(static)
for (int i = 0; i < data.size(); i++) {
my_data.push_back(data[i]);
}
do { // May run 100 times or more
#pragma omp barriered section
{
prepare();
}
#pragma omp single
remaining = 0;
remaining += compute1(my_data);
#pragma omp barrier
remaining -= compute2(my_data);
#pragma omp barriered section
{
cleanup(my_data);
}
} while (remaining > 0);
}
Есть ли хороший способ реализовать такую ​​вещь, используя функции OpenMP и/или функции синхронизации C ++?>

Подробнее здесь: https://stackoverflow.com/questions/796 ... on-barrier
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»