Директивы разгрузки OpenMP 4.0

Я тестирую узел с тремя картами Intel Xeon Phi. Моя идея состоит в том, чтобы использовать директивы OpenMP 4.0 для разгрузки задач на сопроцессоры. Код выглядит следующим образом (взято с http://goo.gl/9Ztq0e):

/***************************************************************************************************
* FILE          : openmp4x-reduce-1Darray.c
*
* INPUT         : Nil
*
* OUTPUT        : Displays Host and device reduce sum
*
* CREATED       : August,2013
*
* EMAIL         : [email protected]
*
***************************************************************************************************/

#include <stdio.h>

 #define SIZE 10000
 #pragma omp declare target

int reduce(int *inarray)
{

  int sum = 0;
  #pragma omp target map(inarray[0:SIZE]) map(sum)
  {
    for(int i=0;i<SIZE;i++)
    sum += inarray[i];
  }
  return sum;
}

int main()
{
  int inarray[SIZE], sum, validSum;

  validSum=0;
  for(int i=0; i<SIZE; i++){
  inarray[i]=i;
  validSum+=i;
  }

 sum=0;
 sum = reduce(inarray);

 printf("sum reduction = %d,validSum=%d\n",sum, validSum);
}

Я скомпилировал компилятором intel/16.0.1.150 (читал на сайте Intel, что этот компилятор поддерживает OpenMP 4.0, может ошибаюсь). В дополнение к этому я использовал переменные:

export MIC_ENV_PREFIX=MIC
export MIC_OMP_NUM_THREADS=240
export MIC_KMP_AFFINITY=granularity=fine,compact

icc -openmp -std=c99 -qopt-report2 openmp_4.0_reduce_1Darray.c -o exec

Проблема в том, что когда я запускаю код, я использую micsmc-gui (графический интерфейс), чтобы увидеть производительность ядер на сопроцессорах. Чего я не понимаю, так это того, почему на каждом сопроцессоре используется только одно ядро, независимо от количества потоков, которые я использую на MIC, см. красный прямоугольник на каждом MIC на рисунке.

производительность MIC

Любое предложение?

Спасибо.


person armando    schedule 02.02.2016    source источник
comment
Этого и следовало ожидать. В вашем коде нет конструкций совместной работы, поэтому он выполняется последовательно на сопроцессоре.   -  person Hristo Iliev    schedule 02.02.2016


Ответы (1)


Вы не указали никакой параллельной директивы, поэтому цикл последовательный. Попробуйте добавить директиву openmp parallel, чтобы распределить итерации цикла по нескольким ядрам MIC.

    int reduce(int *inarray)
    {

      int sum = 0;
      #pragma omp target map(inarray[0:SIZE]) map(sum)
      {
        #pragma omp parallel for reduction(+:sum)
        for(int i=0;i<SIZE;i++)
          sum += inarray[i];
      }
      return sum;
    }

Некоторая основная документация: https://computing.llnl.gov/tutorials/openMP/#DO

person Dareg    schedule 24.06.2016