- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要一些帮助来通过给定的随机数生成器使用 openmp 的蒙特卡洛方法并行化 pi 计算,这不是线程安全的。
第一个:This所以线程没有帮助我。
我自己的尝试是以下#pragma omp 语句。我认为 i、x 和 y 变量应该由每个线程初始化,而不应该是私有(private)的。 z 是圆圈中所有命中的总和,因此它应该在 for 循环之后的隐含屏障之后求和。
认为主要问题是随机数生成器的静态变量。我做了一个调用函数的关键部分,这样每次只有一个线程可以执行它。但是 Pi 解决方案不会随着更高的值而扩展。
注意:我不应该使用另一个 RNG,但可以对其进行一些小改动。
int main (int argc, char *argv[]) {
int i, z = 0, threads = 8, iters = 100000;
double x,y, pi;
#pragma omp parallel firstprivate(i,x,y) reduction(+:z) num_threads(threads)
for (i=0; i<iters; ++i) {
#pragma omp critical
{
x = rng_doub(1.0);
y = rng_doub(1.0);
}
if ((x*x+y*y) <= 1.0)
z++;
}
pi = ((double) z / (double) (iters*threads))*4.0;
printf("Pi: %lf\n", pi);;
return 0;
}
这个RNG实际上是一个include文件,但是我不确定我创建的头文件是否正确,所以我将它集成到另一个程序文件中,所以我只有一个.c文件。
#define RNG_MOD 741025
int rng_int(void) {
static int state = 0;
return (state = (1366 * state + 150889) % RNG_MOD);
}
double rng_doub(double range) {
return ((double) rng_int()) / (double) ((RNG_MOD - 1)/range);
}
我也试过将static int状态设为全局,但它并没有改变我的结果,也许我做错了。所以请你能帮我做出正确的改变吗?非常感谢!
最佳答案
您的原始线性全等 PRNG 的循环长度为 49400,因此您只能获得 29700 个唯一测试点。这是用于任何类型的蒙特卡罗模拟的糟糕生成器。即使你做了 100000000 次试验,你也不会更接近 Pi 的真实值,因为你只是一遍又一遍地重复相同的点,结果 z
的最终值和iters
简单地乘以相同的常量,最后在除法期间取消。
Z 玻色子引入的每线程种子稍微改善了这种情况,唯一点的数量随着 OpenMP 线程总数的增加而增加。增加不是线性的,因为如果一个 PRNG 的种子落在另一个 PRNG 的序列中,则两个 PRNG 产生相同的序列,移位不超过 49400 个元素。给定周期长度,每个 PRNG 覆盖总输出范围的 49400/RNG_MOD = 6.7%,这就是两个 PRNG 同步的概率。总共有 RNG_MOD/49400 = 15 个可能的唯一序列。这基本上意味着在最好的播种情况下,您将无法超过 30 个线程,因为任何其他线程只会重复其他一些线程的结果。乘数 2 是因为每个点使用序列中的两个元素,因此如果将序列移动一个元素,可能会得到一组不同的点。
最终的解决方案是完全放弃您的 PRNG 并坚持使用类似 Mersenne twister MT19937 的东西,其循环长度为 219937 − 1 和非常强大的播种算法。如果您不能像您在问题中所述那样使用另一个 PRNG,请至少修改 LCG 的常量以匹配 rand()
中使用的常量:
int rng_int(void) {
static int state = 1;
// & 0x7fffffff is equivalent to modulo with RNG_MOD = 2^31
return (state = (state * 1103515245 + 12345) & 0x7fffffff);
}
请注意 rand()
不是一个好的 PRNG - 它仍然很糟糕。它只比您的代码中使用的好一点。
关于thread-safety - 使用非线程安全随机数生成器更正 C 中 pi monte carlo 的 OpenMP pragma,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20452420/
我最近一直在研究强化学习。为此,我一直在阅读萨顿的名著,但还有一些我还没有完全理解的地方。 对于蒙特卡洛学习,我们可以在首次访问和每次访问算法之间进行选择,并且可以证明两者都渐进地收敛到正确的解决方案
我编写了一个 C++ 程序,用于通过“将随机点放入四分之一圆中并计算它们等”来计算圆周率。现在我的程序在我看来有点慢,我想过一些改进来加快它的速度(源代码在下面)。 我的第一个想法是使用 OpenMP
我目前正在开发一个小程序,我想根据 cultureinfo 清楚地显示日期和时间,如下所示:2017 年 3 月 3 日星期日上午 7:46:57 但是,我希望可以选择任何国家,并根据他们写日期的方式
基本上,这个问题模拟了以下内容: 有一个装有 50 个绿球和 50 个红球的瓮。 我可以从 jar 里取出球,无需更换,规则如下:每取出一个红球,我将损失一美元,每取出一个绿色球,我将获得一美元。 我
更新: 我的编译命令是ghc -O2 Montecarlo.hs。我的随机版本是random-1.1,ghc版本是8.6.4,我的系统是macOS Big Sur 11.1(Intel芯片)。我用来测
我正在尝试使用组标识符 g 在 (y1,...,yN) 上对 ANOVA 进行排列检验.我应该使用 (1)/(g-1) (muhatj - muhat)^2 的总和作为测试统计量,而 muhatj 是
想象一下我递给你一个上面印有“-1”的乒乓球。然后我告诉你从标有“第一袋”的袋子中取出另一个乒乓球。这个袋子里有 30,000 个球,有的标有“-1”,有的标有“0”,有的标有“+1”。无论您抽到哪个
我正在尝试运行一个代码,通过使用蒙特卡罗积分对一维高斯分布方程进行积分来输出高斯分布。我正在尝试使用 mcint 模块。我定义了 mcint 模块中使用的高斯方程和采样器函数。我不确定 mcint 函
此练习的目的是创建营养摄入值的人口分布。之前的数据中有重复的度量,这些已被删除,因此每一行都是数据框中的唯一人。 我有这个代码,当使用少量我的数据框行进行测试时,它工作得很好。对于所有 7135 行,
我已经为 Hold'em Poker 编写了一个平衡器作为一个业余项目。它工作正常,但还有一件事我不满意:在整个模拟手的过程中,评估手的过程大约占用了35%的时间。与迭代和克隆大型数组等其他必须完成的
考虑从 [0,T) 开始按递增顺序给出的点 Y。我们要将这些点视为位于圆周 T 的圆上。现在考虑来自 [0,T) 的点 X 也位于圆周 T 的圆上。 我们说 X 和 Y 之间的距离是 X 中的每个点与
我目前正在使用 python 和 RPY 来使用 R 中的功能。 我如何使用 R 库生成蒙特卡罗样本,以尊重 2 个变量之间的相关性.. 例如 如果变量 A 和 B 具有 85% (0.85) 的相关
我正在尝试用 Python 实现一个简单的蒙特卡洛(我对此还很陌生)。来自 C 我可能走的是最错误的道路,因为我的代码对于我所要求的来说太慢了:对于 60 个 3d 粒子和周期性边界条件(PBC),我
我已经使用 SAS 很长时间了,现在我想用 R 翻译我的代码。我需要帮助来执行以下操作: 生成多个引导样本 对每个样本运行线性回归模型 通过复制样本将参数存储在新数据集中 为了更清晰,我编辑了这段代码
为了近似 Pi 的值,请考虑使用随机值填充数组并测试是否包含单位圆的随机方法, import random as rd import numpy as np def r(_): return rd.r
在我发现的所有计算 pi 的蒙特卡洛示例代码中,x 和 y 都是在 0 和 1 之间随机生成的。例如,示例代码如下所示 Ran rdm(time(NULL)); double x, y;
从这个数据集中,我有我的聚类分析分配的所有患者样本(总共 69 行),并且聚类被标记为第 3 列“Cluster.assigned”,总共 8 个聚类,每个聚类大小不等。其他列包含变量,其中我想测试数
我正在尝试在 Pytorch 上使用 Mc Dropout 实现贝叶斯 CNN,主要思想是通过在测试时应用 dropout 并运行多次前向传递,您可以获得来自各种不同模型的预测。我需要获得不确定性,有
这是我想用 R 做的算法: 模拟来自 ARIMA 的 10 个时间序列数据集模型通arima.sim()功能 将系列拆分为可能的子系列 2s , 3s , 4s , 5s , 6s , 7s , 8s
下面的 MWE 显示了两种对相同 2D 核密度估计进行积分的方法,这些估计是为 this data 获得的。使用 stats.gaussian_kde()功能。 对所有 (x, y) 执行集成低于阈值
我是一名优秀的程序员,十分优秀!