Parallel processing OpenMP程序比顺序程序慢

Parallel processing OpenMP程序比顺序程序慢,parallel-processing,openmp,Parallel Processing,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); double start=omp_get_wtime(

当我尝试以下代码时

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);
double start=omp_get_wtime();
龙我;
#pragma-omp并行

对于(i=0;i随机数生成器
rand(3)
使用全局状态变量(隐藏在(g)libc实现中)。从多个线程访问这些变量会导致缓存问题,也不是线程安全的。应使用
rand\r(3)
调用
seed
线程专用参数:

long i;
unsigned seed;

#pragma omp parallel private(seed)
{
    // Initialise the random number generator with different seed in each thread
    // The following constants are chosen arbitrarily... use something more sensible
    seed = 25234 + 17*omp_get_thread_num();
    #pragma omp for
    for (i = 0; i <= 1000000000; i++) {
       double x = rand_r(&seed);
    }
}
longi;
无标记种子;
#pragma omp并行专用(seed)
{
//在每个线程中使用不同的种子初始化随机数生成器
//以下常量是任意选择的…请使用更合理的方法
seed=25234+17*omp_get_thread_num();
#pragma omp for

对于(i=0;i),还应注意,由于
double x=rand()
不修改外部状态,编译器可能会试图在顺序版本中优化循环。通常,您应该使用无法优化的代码进行测试。@Vanwaril,
rand()
不是内在的。编译器不知道它是否是纯函数(不是),因此不应该优化调用。非常感谢。现在并行版本花费5秒,而顺序版本花费9秒。@hristoilev,编译器可能会识别状态
rand()
修改,并且不需要外部调用
rand()
,它很可能确定它不会影响程序的输出/结果。
rand()
是一个外部库函数。它在stdlib.h中的声明不能说明它是否修改了外部状态,而且它的代码隐藏在已经编译的库中。GCC提供了
纯外部函数的显式注释。只需在启用最大优化的情况下尝试编译串行版本,然后自己查看即可。