OpenMP程序比顺序程序慢

当我尝试以下代码


double start = omp_get_wtime();


long i;


#pragma omp parallel for

    for (i = 0; i <= 1000000000; i++) {

        double x = rand();

    }


    double end = omp_get_wtime();


    printf("%f\n", end - start);

执行时间约为168秒,而顺序版本仅花费20秒。


我仍然是并行编程的新手。如何获得比顺序版本更快的并行版本?


偶然的你
浏览 592回答 2
2回答

隔江千里

随机数生成器rand(3)使用全局状态变量(隐藏在(g)libc实现中)。从多个线程访问它们会导致缓存问题,而且也不安全。您应该对线程rand_r(3)使用seed参数private 的调用:long i;unsigned seed;#pragma omp parallel private(seed){&nbsp; &nbsp; // Initialise the random number generator with different seed in each thread&nbsp; &nbsp; // The following constants are chosen arbitrarily... use something more sensible&nbsp; &nbsp; seed = 25234 + 17*omp_get_thread_num();&nbsp; &nbsp; #pragma omp for&nbsp; &nbsp; for (i = 0; i <= 1000000000; i++) {&nbsp; &nbsp; &nbsp; &nbsp;double x = rand_r(&seed);&nbsp; &nbsp; }}请注意,并行执行与串行执行时会产生不同的随机数流。我还建议将其erand48(3)作为更好的(伪)随机数源。

千巷猫影

rand()是一个外部库函数。它的声明stdlib.h绝不会说明它是否修改了外部状态,此外,其代码还隐藏在已编译的库中。GCC&nbsp;__atribute__ ((pure))为纯外部功能提供了显式注释。只需尝试在启用最大优化的情况下编译串行版本,然后自己看看。
打开App,查看更多内容
随时随地看视频慕课网APP