我正在尝试使用openmp学习多线程编程。
首先,我正在测试一个带有大量数组访问操作的嵌套循环,然后将其并行化。我附上下面的代码。基本上,我在内部循环中有这个相当大的数组tmp,如果我让它共享以便每个线程都可以访问和更改它,我的代码实际上会随着线程数量的增加而减慢。我写了它,以便每个线程将完全相同的值写入数组tmp。当我将tmp设为私有时,我的速度与线程数成正比。没有。在这两种情况下,我认为操作完全相同。为什么在共享tmp时速度会变慢?是因为不同的线程试图同时访问同一个地址吗?
int main(){
int k,m,n,dummy_cntr=5000,nthread=10,id;
long num=10000000;
double x[num],tmp[dummy_cntr];
double tm,fact;
clock_t st,fn;
st=clock();
omp_set_num_threads(nthread);
#pragma omp parallel private(tmp)
{
id = omp_get_thread_num();
printf("Thread no. %d \n",id);
#pragma omp for
for (k=0; k<num; k++){
x[k]=k+1;
for (m=0; m<dummy_cntr; m++){
tmp[m] = m;
}
}
}
fn=clock();
tm=(fn-st)/CLOCKS_PER_SEC;
}
P.S。:我知道在这里使用clock()并没有真正给出正确的时间。我必须将它除以否。在这种情况下,线程获得“time ./a.out”给出的类似输出。
答案 0 :(得分:5)
这可能是由于缓存争用:如果数组的一部分被两个或更多线程访问,它将被缓存多次,每个核心一个副本:当一个核心需要访问时它,如果数据已被更改,则需要从另一个核心缓存中获取最新版本,这需要一些时间。
答案 1 :(得分:1)
您的代码在tmp
和m
中有竞争条件。我不知道你真正想做什么,但这个链接可能会有所帮助Fill histograms (array reduction) in parallel with OpenMP without using a critical section
我尝试清理你的代码。此代码为每个线程分配tmp
的内存,以解决tmp
中的错误共享问题。
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main() {
int k,m,dummy_cntr=5000;
long num=10000000;
double *x, *tmp;
double dtime;
x = (double*)malloc(sizeof(double)*num);
dtime = omp_get_wtime();
#pragma omp parallel private(tmp, k)
{
tmp = (double*)malloc(sizeof(double)*dummy_cntr);
#pragma omp for
for (k=0; k<num; k++){
x[k]=k+1;
for (m=0; m<dummy_cntr; m++){
tmp[m] = m;
}
}
free(tmp);
}
dtime = omp_get_wtime() - dtime;
printf("%f\n", dtime);
free(x);
return 0;
}
编译
gcc -fopenmp -O3 -std=c89 -Wall -pedantic foo.c