首页 > 解决方案 > 私有设置和类 OMP、随机 C++。结果理解有问题

问题描述

任务是使用 MonteCarlo 和 OpenMP 计算 PI。代码如下:

#include <omp.h>
#include <chrono>
#include <iostream>
#include <random>

#define numSamples 10000000

int main() {

    double I, t1, t2, x, y;
    std::default_random_engine engine;
    auto seed = std::chrono::system_clock::now().time_since_epoch().count();
    std::uniform_real_distribution<double> distr(-1.0, 1.0);
    engine.seed(seed);


    size_t counter = 0;

    t1 = omp_get_wtime();

#pragma omp parallel for reduction(+ : counter) private(x, y) firstprivate(engine, distr)
    for (size_t i = 0; i < numSamples; ++i) {

        x = distr(engine);
        y = distr(engine);

        if (x * x + y * y <= 1) {
            counter++;
        }
    }

    t2 = omp_get_wtime();

    I = 4.0 * (double)counter / numSamples;
    std::cout << "I = " << I << ", t = " << t2 - t1 << "." << std::endl;

    return 0;
}

有一个问题。我应该让每个线程的引擎变量都是私有的,这是可以理解的。但正如我所注意到的,没有必要将distr 变量设为私有。在这种情况下没有竞争条件(如果这个变量是私有的,程序的执行时间是相同的)。为什么会这样

标签: c++randomopenmpmontecarlo

解决方案


std::uniform_real_distribution<double>是一个简单的辅助类。它存储了两个表示分布范围的变量,仅此而已。它operator ()是一个 const 方法。所以在多个线程中使用它不应该导致任何数据竞争。

话虽如此,我不记得标准是承诺过的——不是我读了很多书——复制它几乎不需要时间和空间。那么为什么不复制以防万一呢?并不是说任何人都应该真正关心它。应该是编剧不介意吧。不过,C++11 的各种实现可能会有一些奇怪的东西。

但是,在 CUDA C++ 和 GPU 环境中,由线程私有拥有通常会导致比共享所有权更好的性能(但并非总是如此)。虽然我不知道“omp.h”是否可以使用类似的东西。


推荐阅读