Parallel processing 写入单个向量时OpenMP中的错误共享

Parallel processing 写入单个向量时OpenMP中的错误共享,parallel-processing,openmp,false-sharing,Parallel Processing,Openmp,False Sharing,我学会了使用OpenMP,他给出了一个虚假共享的例子,如下所示。该程序非常简单,用于计算4.0/(1+x*x)的数值积分,x的范围为0到1。代码使用一个向量来包含从0到1的每个x的值4.0/(1+x*x),然后在末尾对向量求和: #include <omp.h> static long num_steps = 100000; double step; #define NUM_THREADS 2 void main() { int i, nthreads; double pi,

我学会了使用OpenMP,他给出了一个虚假共享的例子,如下所示。该程序非常简单,用于计算4.0/(1+x*x)的数值积分,x的范围为0到1。代码使用一个向量来包含从0到1的每个x的值4.0/(1+x*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;
}
#包括
静态长步数=100000;
双台阶;
#定义NUM_线程2
void main()
{
int i,n线程;双pi,和[NUM_线程];
步长=1.0/(双)个步长;
omp_设置_num_线程(num_线程);
#pragma-omp并行
{
int i,id,nthrds;
双x;
id=omp_get_thread_num();
nthrds=omp_get_num_threads();
如果(id==0)nthreads=nthrds;

对于(i=id,sum[id]=0.0;i本教程不断向堆栈溢出问题上的困惑者发送消息-有时自下而上学习不是一个好主意

  • 数组
    sum
    只有
    2===NUM_线程
    项,即
    [线程0的和,线程1的和
    ]项。这些值可能位于同一缓存线上,因此导致错误共享

  • 如果输入和输出向量足够大(即每个线程有数百个元素),您很好。您应该始终使用惯用OpenMP,即为
  • 使用
    并行,而不是本教程有问题的示例中显示的手动工作共享。默认情况下,您很好,因为OpenMP将为同一线程分配相邻索引

    如果您还没有达到教程中的要点,请确保使用内置的reduce关键字,而不是如示例中所示手动将reduce拼凑在一起