【发布时间】:2016-11-19 10:06:23
【问题描述】:
我正在编写一个应该在串行和并行版本中运行的程序。一旦我让它真正完成它应该做的事情,我就开始尝试将它与 OpenMP 并行化(强制)。
问题是我找不到关于何时使用 #pragma 的文档或参考资料。所以我正在尽力猜测和测试。但是使用嵌套循环进行测试并不顺利。
您将如何并行化一系列嵌套循环,例如:
for(int i = 0; i < 3; ++i){
for(int j = 0; j < HEIGHT; ++j){
for(int k = 0; k < WIDTH; ++k){
switch(i){
case 0:
matrix[j][k].a = matrix[j][k] * someValue1;
break;
case 1:
matrix[j][k].b = matrix[j][k] * someValue2;
break;
case 2:
matrix[j][k].c = matrix[j][k] * someValue3;
break;
}
}
}
}
- 在我必须运行的测试中,HEIGHT 和 WIDTH 通常大小相同。一些测试示例是 32x32 和 4096x4096。
- matrix 是一组具有属性 a、b 和 c 的自定义结构
- someValue 是一个双精度值
我知道 OpenMP 并不总是适用于嵌套循环,但欢迎提供任何帮助。
[更新]:
到目前为止,我已经尝试展开循环。它提高了性能,但我在这里增加了不必要的开销吗?我在重用线程吗?我尝试获取每个 for 中使用的线程的 ID,但没有正确。
#pragma omp parallel
{
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
#pragma omp for collapse(2)
for (int j = 0; j < HEIGHT; ++j) {
for (int k = 0; k < WIDTH; ++k) {
//my previous code here
}
}
}
[更新 2]
除了展开循环之外,我还尝试并行化外循环(比展开最差的性能提升)并折叠两个内循环(与展开或多或少相同的性能提升)。这是我得到的时间。
- 串行:~130 毫秒
- 循环展开:~49 毫秒
- 折叠两个最里面的循环:~55 ms
- 并行最外层循环:~83 ms
您认为最安全的选择是什么?我的意思是,对于大多数系统来说,哪个应该是最好的,而不仅仅是我的电脑?
【问题讨论】:
-
抱歉打错了。现在更正@HighPerformanceMark
-
我认为最内层循环中的
i是k的拼写错误? -
是的,@Davislor。现已更正。
-
我已经更新了代码并尝试展开
标签: c++ parallel-processing openmp