使用 OpenMP 进行 LU 分解似乎很慢,需要建议
LU-factorization with OpenMP seems to slow, need advice
我编写了一个代码,它使用 OpenMP 执行 LU 分解。我觉得代码执行得太慢了。我正在使用的计算机有 16 个内核,16 个线程的时间是 12.5s,4 个线程的时间是 14.3s。这是发生并行化的代码部分。我是 C 编程的新手,感觉我错过了一些正在减慢多线程速度的东西。
/*__Initialize lock__*/
omp_lock_t lock[n];
for(i=0;i<n;i++)
omp_init_lock(&lock[i]);
/*___Create theads____*/
#pragma omp parallel private(i,j,k,thread) num_threads(nThreads)
{
thread=omp_get_thread_num();
#pragma omp for schedule(static)
for(i=0;i<n;i++) omp_set_lock(&lock[i]);
if(thread==0)
omp_unset_lock(&lock[0]);
for(i=0;i<n;i++){
div=1/U[i][i];
#pragma omp for schedule(static)
for(j=i+1;j<n;j++)
L[j][i]=U[j][i]*div;
#pragma omp for schedule(static)
for(j=i+1;j<n;j++){
for(k=i;k<n;k++)
U[j][k]=U[j][k]-L[j][i]*U[i][k];
if(j==i+1)
omp_unset_lock(&lock[i+1]);
}
}
}
根据您提供的代码,在我看来您不需要任何锁,请尝试以下并行版本:
#pragma omp parallel num_threads(nThreads)
{
for(int i=0;i<n;i++){
div=1/U[i][i];
#pragma omp for schedule(static)
for(j=i+1;j<n;j++)
L[j][i]=U[j][i]*div;
#pragma omp for schedule(static)
for(int j=i+1;j<n;j++){
for(int k=i;k<n;k++)
U[j][k]=U[j][k]-L[j][i]*U[i][k];
}
}
我编写了一个代码,它使用 OpenMP 执行 LU 分解。我觉得代码执行得太慢了。我正在使用的计算机有 16 个内核,16 个线程的时间是 12.5s,4 个线程的时间是 14.3s。这是发生并行化的代码部分。我是 C 编程的新手,感觉我错过了一些正在减慢多线程速度的东西。
/*__Initialize lock__*/
omp_lock_t lock[n];
for(i=0;i<n;i++)
omp_init_lock(&lock[i]);
/*___Create theads____*/
#pragma omp parallel private(i,j,k,thread) num_threads(nThreads)
{
thread=omp_get_thread_num();
#pragma omp for schedule(static)
for(i=0;i<n;i++) omp_set_lock(&lock[i]);
if(thread==0)
omp_unset_lock(&lock[0]);
for(i=0;i<n;i++){
div=1/U[i][i];
#pragma omp for schedule(static)
for(j=i+1;j<n;j++)
L[j][i]=U[j][i]*div;
#pragma omp for schedule(static)
for(j=i+1;j<n;j++){
for(k=i;k<n;k++)
U[j][k]=U[j][k]-L[j][i]*U[i][k];
if(j==i+1)
omp_unset_lock(&lock[i+1]);
}
}
}
根据您提供的代码,在我看来您不需要任何锁,请尝试以下并行版本:
#pragma omp parallel num_threads(nThreads)
{
for(int i=0;i<n;i++){
div=1/U[i][i];
#pragma omp for schedule(static)
for(j=i+1;j<n;j++)
L[j][i]=U[j][i]*div;
#pragma omp for schedule(static)
for(int j=i+1;j<n;j++){
for(int k=i;k<n;k++)
U[j][k]=U[j][k]-L[j][i]*U[i][k];
}
}