【问题标题】:OpenMP parallel for slow down my code (C language)OpenMP 并行以减慢我的代码速度(C 语言)
【发布时间】:2018-03-23 07:49:48
【问题描述】:

我正在尝试使用 openMP 来加快列表排名的并行版本。我的实现如下:

int ListRankingParallel(int *R1,int *S, int N)
{
int i;
int *Q = (int*)malloc(N * sizeof(int));

#pragma omp parallel for private(i)
for (i=0; i<N; i++){

    if( S[i] != -1)R1[i] = 1;
    else R1[i] = 0;
    Q[i] = S[i];

}

#pragma omp parallel for private(i)
for(i=0; i<N; i++)
    while (Q[i] != -1 & Q[Q[i]] != -1) {
        R1[i] = R1[i] + R1[Q[i]];
        Q[i] = Q[Q[i]];
    }

free(Q);

return *R1;
}

我的榜单排名连载版是

int ListRankingSerial(int *R2,int *S, int N)
{
int temp;  
int j,i;
for( i=0; i<N; i++){
    j = 0;
    temp = S[i];
    while(S[i]!=-1)
    {
        j++;
        S[i] = S[S[i]];
    }
    R2[i] = j;
    S[i] = temp;
}

return *R2;
}

当我分别运行它们时,使用

get_walltime(&S1);
ListRankingParallel(R1,S,N);
get_walltime(&E1);

get_walltime(&S3);
ListRankingSerial(R3,S,N);
get_walltime(&E3);

如果我在我的 Mac 上运行我的代码,并行版本的运行速度明显快于串行版本。但是,如果我在另一个 linux 集群上运行它,并行版本比串行版本慢一倍。

在我的 Mac 上,我使用

编译我的代码
gcc-7 -fopenmp <file name>.c 

在集群上,使用

gcc -fopenmp <file name>.c 

如果你想测试我的代码,请使用:

int main(){

int N = 1e+5;
int *S = (int*)malloc(N * sizeof(int));
int *R1 = (int*)malloc(N * sizeof(int));
int *R3 = (int*)malloc(N * sizeof(int));
double S1,S2,S3,E1,E2,E3;
int i;

for( i = 0; i < N; i++)
    S[i] = i+1;

S[N-1] = -1;

get_walltime(&S1);
ListRankingParallel(R1,S,N);
get_walltime(&E1);
printf("%f\n",E1-S1);

get_walltime(&S3);
ListRankingSerial(R3,S,N);
get_walltime(&E3);
printf("%f\n",E3-S3);

}

谁能给我一些建议?谢谢!

【问题讨论】:

  • 您通过以非同步方式访问同一变量来创建竞争条件。尝试在更新数组之前插入 #pragma omp atomic 行。
  • @AlexQuilliam 我还是不太明白如何处理数组竞争条件。您能否更具体地说明我的代码的修改?谢谢!
  • 列表排名是一个众所周知的难以并行化的问题。不要指望简单的 OpenMP 代码可以做到这一点。您确实需要一种避免并发写入同一数组元素的策略。使用 atomic 执行此操作是一种方法,但代价高昂,因此您不会看到任何性能提升。有很多关于 LR 的文献,请阅读。此外,现在您应该在 for 循环中声明 i 而不是 private(i)
  • 顺便说一句,在 C 语言中,#include &lt;stdlib.h&gt;to cast the return value of malloc() and family 更好。
  • 除了你的并行代码的竞争条件之外,永远不要对没有优化开关编译的代码进行性能测量。至少尝试使用-O3 和更好的-O3 -march=native -mtune=native

标签: c openmp hpc


【解决方案1】:

你确定它在多个线程上运行吗?

您应该设置 OMP_NUM_THREADS 环境变量 或打电话 omp_set_num_threads() 在主要的开始。您可以使用omp_get_max_threads() 获取可用的线程总数并执行类似的操作

max_threads = omp_get_max_threads()
omp_set_num_threads(max_threads)

this answer中查看更多关于设置线程数的信息。

编辑:您还可以检查omp_get_num_threads() 正在使用多少线程。

【讨论】:

  • 谢谢!虽然我在评论中提到了这个问题。但你是对的!我解决了指定线程数的问题!
猜你喜欢
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
  • 2021-08-28
  • 2016-10-08
相关资源
最近更新 更多