【发布时间】:2021-05-01 09:11:13
【问题描述】:
我正在尝试使用 OpenMP 并行化代码,我当前输入大小的串行时间约为 9 秒,我有以下形式的代码:
int main()
{
/* do some stuff*/
myfunction();
}
void myfunction()
{
for (int i=0; i<n; i++)
{
//it has some parameters but that is beyond the point I guess
int rand = custom_random_generator();
compute(rand);
}
}
所以这里随机生成器可以并行执行,因为没有依赖关系,计算函数也是如此,所以我试图并行这个部分,但我所有的尝试都失败了,首先想到的是这些函数作为任务,因此它们并行执行,但结果较慢,这就是我所做的
void myfunction()
{
for (int i=0; i<n; i++)
{
#pragma omp task
{
//it has some parameters but that is beyond the point I guess
int rand=custom_random_generator();
compute(rand);
}
}
}
结果:23 秒,是串行时间的两倍多
将任务放在compute() 上只会导致相同的结果
更糟糕的尝试:
void myfunction()
{
#pragma omp parallel for
for (int i=0; i<n; i++)
{
//it has some parameters but that is beyond the point I guess
int rand=custom_random_generator();
compute(rand);
}
}
结果:45 秒
从理论上讲,为什么会发生这种情况?我知道任何人要告诉我的确切问题,他们都需要一个最小可重复的例子,但我的目标是理解可以解释我的问题并自己应用它们的不同理论,为什么要并行化“令人尴尬的并行”一段代码导致更差的性能?
【问题讨论】:
-
导致所有这些开销的其他原因不仅仅是线程创建,我怀疑错误共享、缓存失效等,你有多少个内核?
-
我有一个带有英特尔酷睿 i5 的 macbook air 2019,所以我有 2 个内核但并行运行 4 个线程,因为它支持超线程@dreamcrash
-
你能告诉我#pragma omp parallel for num_threads(1),然后是 num_threads(2) 的时间吗?
-
没问题,寻找竞态条件共享状态,包括外部函数调用
-
你的任务代码没有并行性! (代码中的任何地方都没有并行指令)。您可能还想查看有关并行随机数生成的论文,这不是一项简单的任务。 (例如并行随机数:像 1、2、3 一样简单 - The Salmons thesalmons.org/john/random123/papers/random123sc11.pdf)