Optimizing a 3D-Loop (C++)
Optimizing a 3D-Loop (C++)
我正在用c++开发一个多网格求解器,现在我正在努力提高串行性能。其中最耗时的部分是平滑,在我的例子中是一个连续的过度松弛解算器。它看起来像这样(我希望它是不言自明的):
int idx;
int strideY = stride_[level][0];
int strideZ = stride_[level][1];
for(int i = 0; i < steps; ++i) {
for(int z = 1; z <= innerGridpoints_[level][2]; ++z) {
for(int y = 1; y <= innerGridpoints_[level][1]; ++y) {
idx = getIndexInner(level, 1,y,z);
for(int x = 1; x <= innerGridpoints_[level][0]; ++x, ++idx) {
grid[idx] = (1. - omega) * grid[idx] + omega * 1./6. * (grid[idx+1] + grid[idx-1] +
grid[idx + strideY] + grid[idx - strideY] +
grid[idx + strideZ] + grid[idx - strideZ] -
spacing_[level] * spacing_[level] * rhs[idx]);
}
}
}
}
我已经做了一些优化:循环的定位使得内部循环提供最多的局部条目(即相邻元素沿着x维),以及idx的预计算(尽管这是一个内联函数,但它这样节省了相当多的时间)。我也尝试过阻塞,即不是在整个网格上迭代,而是只在小块上迭代以增加局部性,但这没有任何影响。我的最后一个想法是尝试一些循环展开,但实际上我并不期望从中得到很大的改进。我在想,也许在内存访问方面有一些可能的改进。欢迎任何提示:)
仅供参考:网格大小从非常小到255x255x255不等。此外,网格在每个维度上都有一些边界,由少量的行组成,即迭代不是在整个网格上。
一个好的优化编译器无论如何都会为您做大多数简单的事情,所以总是衡量您所做的更改是否确实改善了事情。并且,检查(并学会理解)生成的汇编代码,看看编译器实际上在做什么。
但是有一些事情我会尝试,因为表达式很复杂,甚至好的优化器有时也需要一些帮助:-
首先,将内部循环中的不变子表达式提升到周围循环中。在您的示例中,明显的是spacing_[level] * spacing_[level]
和omega * 1./6.
另一种尝试是使idx成为指针而不是数组索引,并在循环中增加指针。
int *idx = &grid[getIndexInner(level, 1,y,z)]; // assuming grid is array of ints.
你的表达式开始看起来像这样
*idx = (1. - omega) * *idx + omega * 1./6. * (idx[1] + idx[-1] +
idx[strideY] + idx[- strideY] + // etc...
你的优化器(假设它已经打开了??)可能已经在这样做了。但值得一试。正如我所说,没有测量,这是一个毫无意义的练习。
并且,正如@AkiSuihkonen在上面的评论中提到的"首先让它工作"。调试高度优化的代码要困难得多,所以在开始担心性能问题之前,请确保你的算法完全按照应该的方式执行。
- 无法将结构注册为增强几何体3D点
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- OpenGL大的3D纹理(>2GB)非常慢
- 是什么导致了Unity 3D中的"错误线程异常"?
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- CPU 瓶颈;处理具有许多非静态对象的 3D 场景渲染的简单方法
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- "Ill-defined for-loop - loop executes infinitely" (MSVC C6295)
- Arduino:在 loop() 和自定义函数中运行相同的代码时出现问题
- 如何从 3D 曲面网格中删除自相交三角形?
- CUDA 使用共享内存平铺 3D 卷积实现
- 检查框内的 3D 点
- 如何在 3D OpenGL 场景上绘制 SDL 2D 矩形?
- Frank Luna 在他的书"使用 DirectX12 进行 3D 游戏编程"的介绍中盒子示例的问题
- 使用 C++在 OpenGL 中对 3D 多边形进行纹理处理
- 使用 C++在 OpenGL 中移动自动旋转的 3D 多边形
- 是否可以使用 DirectX 3D 11 绘制由三角形组成的圆?
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- Optimizing a 3D-Loop (C++)