C++ openMP练习omp_bug2.c

C++ openMP练习omp_bug2.c,c++,multithreading,multiprocessing,openmp,C++,Multithreading,Multiprocessing,Openmp,这是OpenMP网站上的练习: 这意味着变量“total”有问题 这是网站上的帮助 以下是我的解决方案:你认为这是正确的方法吗 #include "stdafx.h" #include <omp.h> #include <stdio.h> #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) { int nthreads, i, tid; float total; /*** Spawn par

这是OpenMP网站上的练习:


这意味着变量“total”有问题

这是网站上的帮助

以下是我的解决方案:你认为这是正确的方法吗

#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;

/*** Spawn parallel region ***/
#pragma omp parallel private(total,tid)
  {
  /* Obtain thread number */
  tid = omp_get_thread_num();
  total= 0.0;
  /* Only master thread does this */
  if (tid == 0) {
    nthreads = omp_get_num_threads();
    printf("Number of threads = %d\n", nthreads);
    }
  printf("Thread %d is starting...\n",tid);



  #pragma omp parallel for schedule(static,10)\
  private(i)\
  reduction(+:total)
  for (i=0; i<1000000; i++) 
     total = total + i*1.0;

  printf ("Thread %d is done! Total= %e\n",tid,total);

  } /*** End of parallel region ***/
}

是的,您当然希望
total
成为线程私有变量。在一个实际示例中,您可能会做的一件事是在最后将线程private
totals
减少为单个全局合计(然后只让一个线程打印结果)。一种方法是简单的

#pragma omp atomic
global_total += total
最后(通过使用减少,有更好的方法)


PS:omp for的循环计数器默认为私有的,因此实际上您不必明确指定它。

可以查看我的编辑吗?这就是您的想法吗?使用
reduce
是惯用的方法(尽管编写带有私有变量和原子添加的简单版本很有用,只是为了了解它在后台的工作方式)。但是您不应该将total设为私有。在这种情况下,它应该是共享的。为什么您认为total应该是共享的而不是私有的?@Androidy考虑一下如何手动实现缩减:每个线程都有一个私有变量,并将其相加。最后,您必须得到所有这些部分和的总和,这是最简单的方法,只需将所有内容原子地添加到一个共享变量中即可。或者换一种方式来考虑:逻辑上只有一个全局和,有n个拷贝没有多大意义。
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int _tmain(int argc, _TCHAR* argv[])
{
int nthreads, i, tid;
float total;

/*** Spawn parallel region ***/
#pragma omp parallel private(total,tid)
  {
  /* Obtain thread number */
  tid = omp_get_thread_num();
  total= 0.0;
  /* Only master thread does this */
  if (tid == 0) {
    nthreads = omp_get_num_threads();
    printf("Number of threads = %d\n", nthreads);
    }
  printf("Thread %d is starting...\n",tid);



  #pragma omp parallel for schedule(static,10)\
  private(i)\
  reduction(+:total)
  for (i=0; i<1000000; i++) 
     total = total + i*1.0;

  printf ("Thread %d is done! Total= %e\n",tid,total);

  } /*** End of parallel region ***/
}
Number of threads = 4
Thread 0 is starting...
Thread 1 is starting...
Thread 0 is done! Total= 4.999404e+011
Thread 2 is starting...
Thread 1 is done! Total= 4.999404e+011
Thread 2 is done! Total= 4.999404e+011
Thread 3 is starting...
Thread 3 is done! Total= 4.999404e+011
#pragma omp atomic
global_total += total