我有一个需要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循环吗?谢谢!
答案 0 :(得分: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调用仅由主线程调用。