2016-08-17 3 views
0

У меня проблема с задачами OpenMP. Я пытаюсь создать параллельную версию цикла «для», используя задачи omp. Тем не менее, время выполнения этой версии почти в 2 раза дольше, чем базовая версия, где я использую omp for, и я не знаю, в чем причина этого. Посмотрите на коды мехов:Параллелизм задач OpenMP - проблема с производительностью

OMP для версии:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    for(int ts=0; ts<1000; ++ts) 
    { 
     #pragma omp for 
     for(int i=0; i<size; ++i) 
     { 
      array_31[i] = array_11[i] * array_21[i]; 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp for: " << t.time() << endl; 

OMP версия задачи:

t.start(); 
#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      for(int th=0; th<threadsNumber; ++th) 
      { 
       #pragma omp task 
       { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        } 
       }      
      } 

      #pragma omp taskwait 
     } 
    } 
} 
t.stop(); 
cout << "Time of omp task: " << t.time() << endl; 

В версии задачи я разделить цикл таким же образом, как и в OMP для. Каждая из задач должна выполнять одинаковое количество итераций. Общее количество заданий равно общему количеству потоков.

Результаты деятельности:

Time of omp for: 4.54871 
Time of omp task: 8.43251 

Что может быть проблема? Возможно ли достичь одинаковой производительности для обеих версий? Прикрепленные коды просты, потому что я хотел только проиллюстрировать свою проблему, которую я пытаюсь решить. Я не ожидаю, что обе версии дают мне такую ​​же производительность, однако я бы хотел уменьшить разницу.

Спасибо за ответ. С уважением.

ответ

0

Я думаю, что проблема здесь в накладных расходах. Когда вы объявляете цикл как параллельный, он назначает все потоки для выполнения своей части цикла for все сразу. Когда вы запускаете задачу, она должна проходить весь процесс настройки при каждом запуске задачи. Почему бы просто не сделать следующее.

#pragma omp parallel num_threads(threadsNumber) 
{ 
    #pragma omp master 
    { 
     for(int ts=0; ts<1000; ++ts) 
     { 
      #pragma omp for 
      for(int th=0; th<threadsNumber; ++th) 
      { 
        for(int i=th*blockSize; i<th*blockSize+blockSize; ++i) 
        { 
         array_32[i] = array_12[i] * array_22[i]; 
        }     
      } 


     } 
    } 
} 
0

Я бы сказал, что вопрос, который вы экспериментируете здесь связано с близостью данных: при использовании #pragma omp for распределение итераций между потоками всегда одинакова для всех значений ts, в то время как с задачами у вас нет способа указать привязку задач к потокам.

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

  • t1_for: 2.041443s
  • t1_tasking: 2.159012s

(я использовал GCC 5.3.0 20151204)

Смежные вопросы