Параллельное обновление содержимого массива в OpenMP - Параллельный элемент добавления - PullRequest
0 голосов
/ 25 июня 2018

У меня есть следующий код, который я хотел бы сделать его параллельным (псевдокод)

int na = 10000000;
int nb = na;
double A[na];
double B[2*na];
double a;

for(int j=0;j<nb;j++)
{
  i = rand() % na;
  A[i]+=5.0*i;
  B[i+10]+=6.0*i*i;
}

Конечно, я не могу использовать #pragma omp parallel for, потому что иногда (что не может быть предсказано) один и тот же элемент будет доступен двум потокам одновременно. Как можно распараллелить этот блок кода? Спасибо

1 Ответ

0 голосов
/ 25 июня 2018

Есть два способа сделать это:

  • Использовать атомарное обновление значений

    #pragma omp parallel for
    for(int j=0;j<nb;j++)
    {
        // make sure to declare i locally!
        int i = fun();
        #pragma omp atomic
        A[i]+=5.0*i;
    }
    

    Это самый простой способ. Каждая запись выполняется атомарно и, следовательно, дороже. Также необходимо учитывать, что доступ к смежным элементам из нескольких потоков становится дорогим (ложное совместное использование). Используйте это, если A велико, и вы делаете много вычислений за аптейт.

  • Использовать массив-сокращение

    #pragma omp parallel for reduction(+:A)
    for(int j=0;j<nb;j++)
    {
        // make sure to declare i locally!
        int i = fun();
        A[i]+=5.0*i;
    }
    

    Это создает локальную копию A для каждого потока, которая добавляется вместе во внешнюю A после параллельной области. Это требует больше памяти и некоторых вычислений после этого, но сам параллельный код может работать наиболее эффективно. Используйте это, если A мало и мало вычислений для каждого обновления.

Кстати: никогда не используйте rand() в параллельных приложениях, оно не определено как поточно-ориентированное, а иногда оно реализуется с блокировкой и становится ужасно неэффективным .

РЕДАКТИРОВАТЬ: В вашем примере с B вы можете безопасно применять omp atomic или reduction отдельно к оператору, поскольку каждая операция должна выполняться только атомарно независимо.

...