pthread并发运行线程c

Jul*_*osa 5 c multithreading pi

我需要在c中用pthread制作莱布尼兹算法,现在我有了这段代码,但目前线程实现与顺序实现的时间相同,我认为它不是同时运行的。有人可以看到错误吗。

\n\n

谢谢!!

\n\n
#include<stdio.h>\n#include<math.h>\n#include<pthread.h>\n#include<stdlib.h>\n#define NUM_THREADS 2\n#define ITERATIONS 100000000\ndouble result = 0.0;\nvoid *leibniz(void *threadid){\n  int size = ITERATIONS/NUM_THREADS;\n  int start = (long)threadid * size;\n  int end = ((long)threadid+1) * size;\n  int i;\n  for(i = start; i<end; i++){\n    int denom = 2*i+1;\n    result += pow(-1.0, i) * (1.0/denom);\n  }\n}\n\nint main(){\n  pthread_t threads[NUM_THREADS];\n  long t;\n  int rc;\n\n  // CREATE\n  for(t=0;t<NUM_THREADS;t++){\n    rc = pthread_create(&threads[t], NULL, leibniz, (void *)t);\n    if(rc){\n      printf("ERROR: return code %d\\n", rc);\n    }\n  }\n  // JOIN\n  for(t=0;t<NUM_THREADS;t++){\n    rc = pthread_join(threads[t], NULL);\n    if(rc){\n      printf("ERROR: return code %d\\n", rc);\n      exit(-1);\n    }\n  }\n  printf("Pi %f\\n", result*4);\n  exit(0);\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

感谢 Jean-Fran\xc3\xa7ois Fabre 我做了这些更改,现在它可以工作了!

\n\n
double result=0.0;\n\nvoid *leibniz(void *threadid){\n  double local = 0.0;\n  int size = ITERATIONS/NUM_THREADS;\n  int start = (long)threadid * size;\n  int end = ((long)threadid+1) * size;\n  int i;\n  for(i = start; i<end; i++){\n    local += (i%2==0 ? 1 : -1) * (1.0/(2*i+1));\n  }\n  result += local*4;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Jea*_*bre 3

我将尝试回答。

即使您的应用程序是多线程的,也不能保证每个核心有 1 个 FPU。我对此知之甚少,但我认为一些 AMD 处理器实际上在核心之间共享FPU。

由于您的循环基本上是添加 和pow,因此 99% 是 FPU 计算,因此如果 FPU 在您的计算机上共享,则可以解释瓶颈。

您可以通过不只调用pow计算-1or来减少 FPU 使用量1,这将是一个标量操作,并且可能会产生影响。只需使用-1ifi为奇数,1否则,或在每次迭代时否定外部 1/-1 变量。

另外,为了避免竞争条件,将结果累积在本地结果中,并将其添加到最后(最后通过互斥体保护添加会更好)

double result = 0.0;
void *leibniz(void *threadid){
  double local = 0.0;
  int size = ITERATIONS/NUM_THREADS;
  int start = (long)threadid * size;
  int end = ((long)threadid+1) * size;
  int i;
  for(i = start; i<end; i++){
    int denom = 2*i+1;
    // using a ternary/scalar speeds up the "pow" computation, multithread or not
    local += (i%2 ? -1 : 1) * (1.0/denom);
  }
  // you may want to protect that addition with a pthread_mutex
  // start of critical section
  result += local;
  // end of critical section
}
Run Code Online (Sandbox Code Playgroud)

http://wccftech.com/amd-one-fpu-per-core-design-zen-processors/