写入单个向量时在OpenMP中进行虚假共享

时间:2018-09-11 20:19:30

标签: parallel-processing openmp false-sharing

我使用Tim Matterson's lecture notes学习了OpenMP,他给出了一个错误共享的示例,如下所示。该代码很简单,用于从4.0 /(1 + x * x)的数值积分计算pi,x的范围为0到1。该代码使用向量包含4.0 /(1 + x * x)的值对于从0到1的每个x,然后将向量求和:

#include <omp.h>
static long num_steps = 100000;
double step;
#define NUM_THREADS 2
void main()
{
    int i, nthreads; double pi, sum[NUM_THREADS];
    step = 1.0/(double)num_steps;
    omp_set_num_threads(NUM_THREADS);
    #pragma omp parallel
    {
        int i, id, nthrds;
        double x;
        id = omp_get_thread_num();
        nthrds = omp_get_num_threads();
        if (id == 0) nthreads = nthrds;
        for (i=id, sum[id]=0.0; i<num_steps; i=i+nthrds){
            x = (i+0.5)*step;
            sum[id] += 4.0/(1.0+x*x);
        }
    }
    for (i=0; pi=0.0; i<nthreads;i++) pi += sum[i]*step;
}

在此示例中,我对虚假共享存在一些疑问:

  1. 是否由于将写入数组的作业间歇性地分配在两个线程(即[thread0,thread1,thread0,thread1,...])之间而导致了错误共享?如果我们使用#pragma omp parallel for,那么该数组将被划分为[thread0,thread0,thread0,....,thread1,thread1,thread1,...],那么我们仍然会有错误的共享,因为每个线程正在访问的地址是否彼此相距遥远?
  2. 如果我有一个使用#pragma omp parallel for来写与我的输入向量成一比一的输出向量的工作(例如,输入是预测变量矩阵,而输出是一个向量,则预测),那么我何时需要担心虚假共享?

1 个答案:

答案 0 :(得分:1)

本教程不断在Stack Overflow上发送混乱的消息-有时从下至上学习不是一个好主意。

  1. 数组sum仅具有2 === NUM_THREADS个条目,即[sum of thread 0, sum of thread 1]。这些值可能在同一高速缓存行上,因此导致错误共享。

  2. 如果输入和输出向量足够(即每个线程数百个元素),则可以。您应该始终使用惯用的OpenMP,即使用parallel for而不是本教程有问题的示例中展示的手动工作共享。那么默认情况下您就可以了,因为OpenMP会将相邻的索引分配给同一线程。

如果您在本教程中没有讲到重点,请确保使用内置的reduce关键字,而不是像示例中所展示的那样手动砍在一起。

相关问题