【发布时间】:2011-10-28 05:30:08
【问题描述】:
我有两种测量指标的场景,例如计算时间和并行加速(sequential_time/parallel_time)。
场景 1:
顺序时间测量:
startTime=omp_get_wtime();
for loop computation
endTime=omp_get_wtime();
seq_time = endTime-startTime;
并行时间测量:
startTime = omp_get_wtime();
for loop computation (#pragma omp parallel for reduction (+:pi) private (i)
for (blah blah) {
computation;
}
endTime=omp_get_wtime();
paralleltime = endTime-startTime;
speedup = seq_time/paralleltime;
场景 2:
顺序时间测量:
for loop{
startTime=omp_get_wtime();
computation;
endTime=omp_get_wtime();
seq_time += endTime-startTime;
}
并行时间测量:
for loop computation (#pragma omp parallel for reduction (+:pi, paralleltime) private (i,startTime,endTime)
for (blah blah) {
startTime=omp_get_wtime();
computation;
endTime=omp_get_wtime();
paralleltime = endTime-startTime;
}
speedup = seq_time/paralleltime;
我知道场景 2 不是最好的生产代码,但我认为它通过忽略 openmp 生成和管理(线程上下文切换)多个线程所涉及的开销来衡量实际的理论性能。所以它会给我们一个线性加速。但是场景 1 考虑了产生和管理线程所涉及的开销。
我的疑问是: 在场景 1 中,我得到了一个从线性开始的加速,但随着我们转向更多的迭代次数而逐渐减少。在场景 2 中,无论迭代次数如何,我都能获得完全的线性加速。有人告诉我,实际上,场景 1 将给我一个线性加速,而不管迭代次数如何。但我认为这不会因为线程管理导致的高过载。有人可以向我解释为什么我错了吗?
谢谢!对于这篇相当长的帖子感到抱歉。
【问题讨论】:
-
方案 2 中的并行时间测量不正确,因为在每次迭代中,您都会在同一线程上重新编写上一次迭代获得的结果。如果你把它改成
paralleltime += endTime-startTime;(注意+=),你将总结所有迭代的时间,这将与seq_time基本相同。 -
这就是为什么我在 pi 和 paralleltime 上执行 reduce 操作 #pragma omp parallel for reduction (+:pi, paralleltime) private (i,startTime,endTime)
-
减少
paralleltime不会使您的程序正确。您可以查看 OpenMP 规范,特别是第 2.9.3.6 节以了解详细信息。简而言之,归约变量的每个私有副本都会累积由同一线程执行的几次循环迭代的结果。为了说明,让我们假设第 1 次和第 2 次循环迭代由同一个线程执行;然后第 2 次迭代将其时间写入第 1 次迭代的时间,而第 1 次迭代将丢失。 -
谢谢阿列克谢!我不知道减少是以这种方式起作用的..
标签: performance parallel-processing openmp