只有在将数组设为私有后才能进行多线程加速

Gre*_*Eye 1 c multithreading openmp

我正在尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)

PS:我知道在这里使用clock()并没有真正给出正确的时间.我必须将它除以否.在这种情况下,线程获得"time ./a.out"给出的类似输出.

Pra*_*eek 5

这可能是由于缓存争用:如果数组的一部分被两个线程或更多线程访问,它将被缓存多次,每个核心一个副本:当一个核心需要访问它时,如果数据已被更改,它将需要从另一个核心缓存中获取最新版本,这需要一些时间.

  • 当两个或多个线程访问属于同一缓存行的数组元素时,它被称为_false sharing_,如果两个或多个线程同时访问同一个数组元素,则称为_true sharing_. (2认同)