2016-08-11 2 views
1

У меня есть итеративный алгоритм, который требует openmp и MPI для ускорения. Вот мой кодкак запустить многопроцессор в цикле While в openmp + mpi

#pragma omp parallel 
while (allmax > E) /* The precision requirement */ 
{ 
    lmax = 0.0; 
    for(i = 0; i < m; i ++) 
    { 
     if(rank * m + i < size) 
     { 
      sum = 0.0; 
      for(j = 0; j < size; j ++) 
      { 
       if (j != (rank * m + i)) sum = sum + a(i, j) * v(j); 
      } 
      /* computes the new elements */ 
      v1(i) = (b(i) - sum)/a(i, rank * m + i); 
      #pragma omp critical 
      { 
       if (fabs(v1(i) - v(i)) > lmax) 
        lmax = fabs(v1(i) - v(rank * m + i)); 
      } 
     } 
    } 
    /*Find the max element in the vector*/   
    MPI_Allreduce(&lmax, &allmax, 1, MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD); 
    /*Gather all the elements of the vector from all nodes*/ 
    MPI_Allgather(x1.data(), m, MPI_FLOAT, x.data(), m, MPI_FLOAT, MPI_COMM_WORLD); 
    #pragma omp critical 
    { 
     loop ++; 
    } 
} 

Но когда он не получил ускорение, даже не мог получить правильный ответ, то, что случилось с моим кодом? Поддерживает ли openmp цикл while? Спасибо!

+1

По-видимому, вы просите каждый поток выполнить код и обновить общие переменные, что приведет к условиям гонки. Для параллелизма, как OpenMP, так и MPI, вы должны организовать, чтобы каждый поток работал на своем собственном наборе данных, получая производительность, решая сразу несколько независимых проблем. – tim18

+0

@Alexander_Yau, вам нужно рассмотреть, что thread выполнит MPI_Allreduce & MPI_Allgather. Кроме того, предпочтительно использовать атомную операцию для обновления цикла. #pragma omp атомное обновление loop ++; – Angelos

+0

@ Ангелос, 'MPI_Allreduce & MPI_Allgather' находится в состоянии гонки, не так ли? –

ответ

3

Что касается вашего вопроса, конструкция #pragma omp parallel просто порождает потоки OpenMP и выполняет блок после него параллельно. И да, он поддерживает выполнение циклов while в качестве минималистического примера.

#include <stdio.h> 
#include <omp.h> 

void main (void) 
{ 
    int i = 0; 
    #pragma omp parallel 
    while (i < 10) 
    { 
     printf ("Hello. I am thread %d and i is %d\n", omp_get_thread_num(), i); 
     #pragma omp atomic 
     i++; 
    } 
} 

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

Как насчет этого изменения в вашем коде?

while (allmax > E) /* The precision requirement */ 
{ 
    lmax = 0.0; 

    #pragma omp parallel for shared (m,size,rank,v,v1,b,a,lmax) private(sum,j) 
    for(i = 0; i < m; i ++) 
    { 
     if(rank * m + i < size) 
     { 
      sum = 0.0; 
      for(j = 0; j < size; j ++) 
      { 
       if (j != (rank * m + i)) sum = sum + a(i, j) * v[j]; 
      } 
      /* computes the new elements */ 
      v1[i] = (b[i] - sum)/a(i, rank * m + i); 

      #pragma omp critical 
      { 
       if (fabs(v1[i] - v[i]) > lmax) 
        lmax = fabs(v1[i] - v(rank * m + i)); 
      } 
     } 
    } 

    /*Find the max element in the vector*/   
    MPI_Allreduce(&lmax, &allmax, 1, MPI_FLOAT, MPI_MAX, MPI_COMM_WORLD); 

    /*Gather all the elements of the vector from all nodes*/ 
    MPI_Allgather(x1.data(), m, MPI_FLOAT, x.data(), m, MPI_FLOAT, MPI_COMM_WORLD); 

    loop ++; 
} 

Основной while цикл выполняется последовательно, но как только начинается цикл OpenMP, будет порождать работу над несколькими потоками при столкновении с #pragma omp parallel for. Использование #pragma omp parallel for (а не #pragma omp parallel) автоматически распределяет работу цикла с рабочими потоками. Кроме того, вам необходимо указать тип переменных (общий, закрытый) в параллельный регион. Я догадался здесь в соответствии с вашим кодом.

В конце цикла while вызовы MPI вызываются только основным потоком.

+0

Спасибо. Поскольку цикл while может быть 1000+ раз, и каждый раз, когда openmp запускает многопоточность, следует ли мне учитывать стоимость системы или время для запуска многопотоков openmp в каждом цикле? –

+0

@AlexanderYau, большинство runtimes поддерживают потоки живыми, чтобы избежать их создания при каждом параллельном построении omp. – Harald

+0

@AlexanderYau, обратите внимание, что у вас был некоторый векторный доступ с использованием скобок, и я изменил их в скобки, возможно, вам нужно изменить это. – Harald

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