私有部分和 类 OMP,随机 C++。对结果的理解有问题

Private setction and classes OMP, Random C++. Problem with understanding with a result

任务是用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;
}

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

std::uniform_real_distribution<double> 是一个简单的帮手 class。它存储两个指示分布范围的变量,仅此而已。它的 operator () 是一个 const 方法。因此在多个线程中使用它不会导致任何数据竞争。

话虽这么说,我不记得标准曾承诺过它 - 并不是我读了很多 - 并且复制它几乎不需要时间 space。那么为什么不复制以防万一呢?并不是说任何人都应该真正关心它。可能作家没有打扰。虽然,C++11 的各种实现可能会有一些奇怪的东西。

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