For loop OpenMP C并行化嵌套循环速度慢
我一直在尝试并行化嵌套循环,如下所示: 我正在比较这段代码的顺序版本和并行版本的执行时间,但是顺序版本在各种输入下似乎总是有更短的执行时间 程序的输入为:For loop OpenMP C并行化嵌套循环速度慢,for-loop,parallel-processing,openmp,For Loop,Parallel Processing,Openmp,我一直在尝试并行化嵌套循环,如下所示: 我正在比较这段代码的顺序版本和并行版本的执行时间,但是顺序版本在各种输入下似乎总是有更短的执行时间 程序的输入为: numParticles(循环索引) timeStep(不重要,值不变) numTimeSteps(循环索引) numThreads(要使用的线程数) 我环顾了一下网络,尝试了一些东西(nowait),但没有什么真正的改变。我很确定并行代码是正确的,因为我检查了输出。我在这里做错什么了吗 编辑:而且,似乎你不能在C结构上使用reduce
- numParticles(循环索引)
- timeStep(不重要,值不变)
- numTimeSteps(循环索引)
- numThreads(要使用的线程数)
谢谢您的循环可能太小了。创建一个线程来处理循环的一部分会带来开销,因此如果循环太小,并行化版本可能会运行得较慢。另一个考虑因素是可用的核心数量 您的第二条omp指令不太可能有用,因为该循环中的计算量要少得多。我建议把它去掉
编辑:我用numparticle1000和两个线程测试了您的代码。它在30秒内运行。单线程版本在57秒内运行。即使使用numParticles 40,我也看到了显著的加速。这是Visual Studio 2010。您的循环可能太小。创建一个线程来处理循环的一部分会带来开销,因此如果循环太小,并行化版本可能会运行得较慢。另一个考虑因素是可用的核心数量 您的第二条omp指令不太可能有用,因为该循环中的计算量要少得多。我建议把它去掉
编辑:我用numparticle1000和两个线程测试了您的代码。它在30秒内运行。单线程版本在57秒内运行。即使使用numParticles 40,我也看到了显著的加速。这是Visual Studio 2010。我可以想到两个可能的减速来源:a)编译器在顺序版本中进行了一些优化(首先是矢量化),但在OpenMP版本中没有,以及b)线程管理开销。如果还使用单个线程运行OpenMP版本(即,将numThreads设置为1),则很容易检查这两个版本。如果它比顺序慢得多,那么(a)是最可能的原因;如果它类似于sequential,并且比具有2个线程的相同代码更快,那么最有可能的原因是(b) 在后一种情况下,您可以重新构造OpenMP代码以减少开销。首先,在一个循环中没有必要有两个平行区域(#pragma omp parallel);可以有一个平行区域和两个平行循环:
for (t = 0; t <= numTimeSteps; t++) {
#pragma omp parallel num_threads(numThreads)
{
#pragma omp for private(j)
/* The first loop goes here */
#pragma omp for
/* The second loop goes here */
}
}
对于(t=0;t我可以想到两个可能的减速来源:a)编译器在顺序版本中进行了一些优化(首先是矢量化),但在OpenMP版本中没有,以及b)线程管理开销。如果还使用单个线程运行OpenMP版本(即,将numThreads设置为1),则很容易检查这两个版本。如果它比顺序慢得多,那么(a)是最可能的原因;如果它类似于sequential,并且比具有2个线程的相同代码更快,那么最有可能的原因是(b)
在后一种情况下,您可以重新构造OpenMP代码以减少开销。首先,在一个循环中没有必要有两个平行区域(#pragma omp parallel);可以有一个平行区域和两个平行循环:
for (t = 0; t <= numTimeSteps; t++) {
#pragma omp parallel num_threads(numThreads)
{
#pragma omp for private(j)
/* The first loop goes here */
#pragma omp for
/* The second loop goes here */
}
}
用于(t=0;t您使用的编译器是什么?numParticles的值是多少?您的CPU有多少个内核?在linux上使用gcc。numParticles是40,numTimeSteps是100000。CPU有2个内核。我尝试了这两个变量的更高值,但结果仍然是samenumTimeSteps应该没有影响,因为它在并行区域之外。是吗ou启用openmp?(我认为gcc中的-fopenmp)正常。numParticles=200,numTimeSteps=100会发生什么?有两个线程,非线程版本=0秒,线程版本=1秒。我也尝试了500 10000,非线程版本更快(184秒对155秒)您使用的编译器是什么?numParticles的值是多少?您的CPU有多少个内核?在linux上使用gcc。numParticles是40,numTimeSteps是100000。CPU有2个内核。我尝试了这两个变量的更高值,但结果仍然是samenumTimeSteps应该没有影响,因为它在并行区域之外。您是否启用了g openmp?(我认为gcc中的-fopenmp)可以。numParticles=200,numTimeSteps=100会发生什么?有两个线程,非线程版本=0秒,线程版本=1秒。我也尝试了500 10000,非线程版本更快(184秒对155秒)哦,很好,知道它至少可以工作。我在linux上用gcc编译器运行它,这有什么区别吗?有。创建线程的开销可能更大。OpenMP实现可能略有不同。请尝试使用更多的粒子(例如500个)然后看看会发生什么。确保您已经在gcc命令行上启用了OpenMP支持。哦,很高兴知道它至少可以工作。我正在使用gcc编译器在linux上运行此程序。这有什么区别吗?有。创建线程的开销可能会更大。OpenMP实现可能会略有不同。请尝试更多的particles(例如500)并查看发生了什么。确保您在gcc命令行上启用了OpenMP支持。我也在考虑优化…可能是自动矢量化。但您可能认为编译器也会对子循环执行相同的操作?我有点不明白为什么并行区域可以在ti之前启动