为什么并行执行一个函数会显着降低程序速度?
Why would executing a function in parallel significantly slowdown the program?
我正在尝试使用 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 秒
从理论上讲,为什么会这样呢?我知道对于任何人来说,要告诉我确切的问题,他们都需要一个最小的可重现示例,但我从这个问题中得出的目标是理解可以解释我的问题并自己应用它们的不同理论,为什么要并行化一段“令人尴尬的并行”代码导致更差性能?
一种理论可能是与创建和维护多个线程相关的开销。
只有当每次迭代都必须执行更复杂的处理器密集型任务时,才能看到并行编程的优势。
内部有一些简单例程的简单 for 循环不会利用它。
我正在尝试使用 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 秒
从理论上讲,为什么会这样呢?我知道对于任何人来说,要告诉我确切的问题,他们都需要一个最小的可重现示例,但我从这个问题中得出的目标是理解可以解释我的问题并自己应用它们的不同理论,为什么要并行化一段“令人尴尬的并行”代码导致更差性能?
一种理论可能是与创建和维护多个线程相关的开销。
只有当每次迭代都必须执行更复杂的处理器密集型任务时,才能看到并行编程的优势。
内部有一些简单例程的简单 for 循环不会利用它。