Можно ли сделать сокращение на массиве с помощью openmp? - PullRequest
19 голосов
/ 23 сентября 2010

Поддерживает ли OpenMP уменьшение переменной, представляющей массив?

Это будет работать примерно так:

float* a = (float*) calloc(4*sizeof(float));
omp_set_num_threads(13);
#pragma omp parallel reduction(+:a)
for(i=0;i<4;i++){
   a[i] += 1;  // Thread-local copy of a incremented by something interesting
}
// a now contains [13 13 13 13]

В идеале, было бы что-то подобное для параллельной omp, и если у вас достаточно большого количества потоков, чтобы это имело смысл, накопление происходило бы через двоичное дерево.

Ответы [ 5 ]

5 голосов
/ 07 ноября 2016

Уменьшение массива теперь возможно с OpenMP 4.5 для C и C ++.Вот пример:

#include <iostream>

int main()
{

  int myArray[6] = {};

  #pragma omp parallel for reduction(+:myArray[:6])
  for (int i=0; i<50; ++i)
  {
    double a = 2.0; // Or something non-trivial justifying the parallelism...
    for (int n = 0; n<6; ++n)
    {
      myArray[n] += a;
    }
  }
  // Print the array elements to see them summed   
  for (int n = 0; n<6; ++n)
  {
    std::cout << myArray[n] << " " << std::endl;
  } 
}

Выходы:

100
100
100
100
100
100

Я скомпилировал это с GCC 6.2.Вы можете увидеть, какие распространенные версии компилятора поддерживают функции OpenMP 4.5 здесь: http://www.openmp.org/resources/openmp-compilers/

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

3 голосов
/ 24 октября 2010

Только в Fortran в OpenMP 3.0 и, вероятно, только с определенными компиляторами.

См. Последний пример (Пример 3) на:

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

2 голосов
/ 14 мая 2016

Теперь последняя спецификация openMP 4.5 поддерживает сокращение массивов C / C ++.http://openmp.org/wp/2015/11/openmp-45-specs-released/

И последняя версия GCC 6.1 также поддерживает эту функцию.http://openmp.org/wp/2016/05/gcc-61-released-supports-openmp-45/

Но я еще не попробовал.Жаль, что другие могут проверить эту функцию.

1 голос
/ 22 октября 2010

OpenMP не может выполнять сокращения переменных массива или типа структуры (см. ограничения ).

Возможно, вы также захотите прочитать private и shared пункты.private объявляет переменную частной для каждого потока, где shared объявляет переменную, которая будет общей для всех потоков.Я также нашел ответ на этот вопрос очень полезным в отношении OpenMP и массивов.

0 голосов
/ 14 июня 2017

OpenMP может выполнять эту операцию, поскольку OpenMP 4.5 и GCC 6.3 (и, возможно, ниже) поддерживают ее.Пример программы выглядит следующим образом:

#include <vector>
#include <iostream>

int main(){
  std::vector<int> vec;

  #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end()))

  #pragma omp parallel for default(none) schedule(static) reduction(merge: vec)
  for(int i=0;i<100;i++)
    vec.push_back(i);

  for(const auto x: vec)
    std::cout<<x<<"\n";

  return 0;
}

Обратите внимание, что omp_out и omp_in являются специальными переменными и что тип declare reduction должен соответствовать вектору, на который вы планируете уменьшить.

...