gpt4 book ai didi

c - OpenMP:并行工作负载中无加速

转载 作者:行者123 更新时间:2023-12-03 13:23:00 25 4
gpt4 key购买 nike

因此,我无法通过我相当简单的OpenMP并行化for循环来弄清楚这一点。当以相同的输入大小运行时,P = 1的运行时间约为50秒,但是运行P = 2的运行时间约为300秒,而运行P = 4的运行时间约为250秒。
这是并行化的循环

double time = omp_get_wtime();

printf("Input Size: %d\n", n);

#pragma omp parallel for private(i) reduction(+:in)
for(i = 0; i < n; i++) {
double x = (double)(rand() % 10000)/10000;
double y = (double)(rand() % 10000)/10000;
if(inCircle(x, y)) {
in++;
}
}

double ratio = (double)in/(double)n;
double est_pi = ratio * 4.0;
time = omp_get_wtime() - time;
运行时间:
p = 1,n = 1073741824-52.764秒
p = 2,n = 1073741824-301.66秒
p = 4,n = 1073741824-274.784秒
p = 8,n = 1073741824-188.224秒
在具有70Gb RAM的Dual Xeon 5650系统上的FreeNas安装之上,在具有8个Xeon 5650内核和16gb DDR3 EEC RAM的Ubuntu 20.04 VM上运行。
部分解决方案:
循环内的rand()函数在多个线程上运行时会导致时间跳转。

最佳答案

由于rand()使用从上次调用保存的状态来生成下一个PRN,因此它不能同时在多个线程中运行。多个线程将需要同时读取/写入PRNG状态。
POSIX states that rand() need not be thread safe.这意味着您的代码无法正常工作。否则,C库可能会放入一个互斥锁,以便一次只能有一个线程调用rand()。这是正在发生的事情,但是会大大降低代码的速度。线程几乎完全消耗掉了,以尝试访问rand关键部分,因为它们所做的其他任何事情都不会花费很多时间。
要解决此问题,请尝试使用rand_r(),它不使用共享状态,而是传递了它应用于状态的seed值。
请记住,为每个线程使用相同的种子将无法达到增加蒙特卡洛模拟中试验次数的目的。每个线程将只使用完全相同的伪随机序列。尝试这样的事情:

unsigned int seed;
#pragma omp parallel private(seed)
{
seed = omp_get_thread_num();
#pragma omp for private(i) reduction(+:in)
for(i = 0; i < n; i++) {
double x = (double)(rand_r(&seed) % 10000)/10000;
double y = (double)(rand_r(&seed) % 10000)/10000;
if(inCircle(x, y)) {
in++;
}
}
}
顺便说一句,您可能会注意到您的估计不正确。 x和y需要在[0,1]范围内均匀分布,但不是。

关于c - OpenMP:并行工作负载中无加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64850966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com