c++ - 私有设置和类 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 变量设为私有。在这种情况下没有竞争条件(如果这个变量是私有的,程序的执行时间是相同的)。为什么会这样?
解决方案
std::uniform_real_distribution<double>
是一个简单的辅助类。它存储了两个表示分布范围的变量,仅此而已。它operator ()
是一个 const 方法。所以在多个线程中使用它不应该导致任何数据竞争。
话虽如此,我不记得标准是承诺过的——不是我读了很多书——复制它几乎不需要时间和空间。那么为什么不复制以防万一呢?并不是说任何人都应该真正关心它。应该是编剧不介意吧。不过,C++11 的各种实现可能会有一些奇怪的东西。
但是,在 CUDA C++ 和 GPU 环境中,由线程私有拥有通常会导致比共享所有权更好的性能(但并非总是如此)。虽然我不知道“omp.h”是否可以使用类似的东西。
推荐阅读
- python - DHL SOAP 请求
- javascript - 通过类对象的 Windows 事件打开/关闭 requestAnimationFrame
- c# - 将 IAsyncOperation 转换为任务
- flutter - flutter 通知 聊天 快速回复
- python - RuntimeError:事件循环在 discord.py 中关闭
- sql - 存储过程很快,直到它被调用 27 次然后变得缓慢
- python - 多个模型的 Django 外键
- python - 聚合和汇总集合列表的值并返回最高值
- javascript - 无法选择传递具有动态内容的第一个元素
- json - Babashka:在json文件列表中输出有效的json