c++ - 如何使用多线程确定性 PRNG
问题描述
我使用 TBB 对我的应用程序的一部分进行多线程处理。
以下代码在逻辑上负责非确定性行为:
std::mt19937 engine;
std::uniform_real_distribution<double> distribution(-1., 1.);
double x[N];
tbb::parallel_for(0, N, [&](int i)
{
// ... complicated stuff done in this loop
x[i] = distribution(engine);
});
我将代码更改为每个线程使用一个 PRNG,使用 TBB TLS,并使用循环索引为 PRNG 播种。
它似乎有效,但对我来说看起来很奇怪。这是一种常见的做法吗?
tbb::enumerable_thread_specific<std::mt19937> engine;
std::uniform_real_distribution<double> distribution(-1., 1.);
double x[N];
tbb::parallel_for(0, N, [&](int i)
{
// ... complicated stuff done in this loop
engine.local().seed(i);
x[i] = distribution(engine.local());
});
解决方案
我没有使用过这个特定的并行化库。但是,使用多线程
- 必须阅读有关您使用的函数的文档,它们通常不是线程安全的,除非明确声明它是线程安全的。
- 保护数据免受并发访问。例如,通过互斥体或线程屈服构造。
这是一个使用互斥锁/锁的例子
static std::mt19937 engine(std::random_device{}());
std::uniform_real_distribution<double> distribution(-1., 1.);
std::mutex mtx;
double x[N];
tbb::parallel_for(0, N, [&](int i)
{
// ... complicated stuff done in this loop
// extra scope to manage lifetime of lock
{
std::unique_lock<std::mutex> lock(mtx);
x[i] = distribution(engine);
}
});
也许你必须为引擎种子做类似的事情,这也可能不是线程安全的。
推荐阅读
- javascript - 请帮助我.. RE: *FORM FIELDS* 我想隐藏()我的“类型=文本框”,直到在下拉选项中选择其他选项
- android - 如何将微调器选择的位置值和 EditText 值一起插入 SQLite 数据库?
- java - 在 Spring Boot 应用程序中未触发方面
- image - 如何从一天中的特定时间(期间)整理图像?
- paypal-sandbox - 如何在 PayPal 沙箱中更改“John Doe's Test Store”企业名称?
- c++ - 如何在 Windows 中设置最小的 c++ makefile 和项目结构,以通过命令行运行?
- php - 给图片添加水印
- vb.net - 如何将 datagridview 中的值添加到 vb.net 中的饼图中?
- clojure - `map` 函数可以返回向量而不是列表吗?
- javascript - AJAX 调用后 JS 未执行