如何优化C 代码的以下片段 - 卷中的零交叉点
How to optimize the following fragment of C++ code - zero crossings in a volume
我正在努力优化以下代码片段。在320x320x320体积中的每个体素中都调用该函数,其中每个体素是16位灰度值。该音量存储为一系列平面(横截面),每个平面是连续的1D阵列,因此,例如,电流素下方的体素的位置变为CurrentPosition PixelSperrow,其左侧位置为CurrentPosition -1。1。<<<<<<
函数检查体积中的零交叉口以及电流和相邻体素的绝对值是否高于某些阈值。这是Marr-Hildreth边缘检测器的必要部分。
电流置位是电流体素,相对位置也可以是电流体素(在这种情况下,在同一平面以8个方向上检查零交叉点),也可以在其直接在其上方或直接下方。这样,对于每个体素,都进行了27次检查,其中涵盖了3D中所有可能的方向。
也许可以以更快的速度重新排列功能。我已经试图以分支预测的方式来安排检查顺序,但也许有可能进一步加快它的速度。目前,它需要更大的应用程序处理时间为50%,因此需要进行一些优化。
bool zeroCrossing(int16_t* currentPosition, int16_t* relativePosition, int pixelsPerRow, int threshold)
{
return *currentPosition * *(relativePosition - pixelsPerRow - 1) < 0 && abs(*currentPosition + *(relativePosition - pixelsPerRow - 1)) > threshold
|| *currentPosition * *(relativePosition - pixelsPerRow) < 0 && abs(*currentPosition + *(relativePosition - pixelsPerRow)) > threshold
|| *currentPosition * *(relativePosition - pixelsPerRow + 1) < 0 && abs(*currentPosition + *(relativePosition - pixelsPerRow + 1)) > threshold
|| *currentPosition * *(relativePosition - 1) < 0 && abs(*currentPosition + *(relativePosition - 1)) > threshold
|| *currentPosition * *(relativePosition) < 0 && abs(*currentPosition + *(relativePosition)) > threshold
|| *currentPosition * *(relativePosition + 1) < 0 && abs(*currentPosition + *(relativePosition + 1)) > threshold
|| *currentPosition * *(relativePosition + pixelsPerRow - 1) < 0 && abs(*currentPosition + *(relativePosition + pixelsPerRow - 1)) > threshold
|| *currentPosition * *(relativePosition + pixelsPerRow) < 0 && abs(*currentPosition + *(relativePosition + pixelsPerRow)) > threshold
|| *currentPosition * *(relativePosition + pixelsPerRow + 1) < 0 && abs(*currentPosition + *(relativePosition + pixelsPerRow + 1)) > threshold;
}
我的直觉是该代码非常适合并行化。使用AVX(2),或将其卸载到GPU。那将使它在C 的范围之外,但这对于程序的核心功能是合理的。
我假设您已经使用线程并行化操作,因为这很微不足道。请注意,使用AVX,您仍然需要线程;每个CPU核心都有自己的AVX单元。
如果交叉零,则将发生在两个相邻像素之间。在卷中运行时,您需要仅检查每对邻居一次。如果将功能应用于每个像素,则将两次检查每对。(我也将术语像素用于3D图像的元素,我不喜欢术语voxel)。
另外,您检查了共享边缘或顶点的像素对,您只需要检查那些共享脸的像素即可。如果以下图中的像素a
和d
之间的交叉零,则a
和b
之间或a
和c
之间必须存在一个。
a b
c d
因此,对于每个像素,您只需要检查三个邻居,而不是27。
但是,这并不能完全解释您的幅度检查,a
和d
之间的差异可能大于其他两个邻居中的任何一个。但是,我认为这并不重要。
在该注意事项上,您的幅度检查是错误的:如果 a
和 b
的符号不同并且都非常大(重要的零交叉),则abs(a + b)
可能为0,而您不会计算它。您可能想取得差异!
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- Opengl 3.1 GLSL 140 在 C++ 年输出白色在片段着色器中
- 这两个代码片段相似,但显示的结果不同
- 如何替换此示例代码片段中已弃用的handler_type_t或 boost::asio::handler_type?
- 我需要解释给定片段的输出
- 如果我在下面的代码片段中添加"delete[] d;",为什么我得到零?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符
- 任何人都可以解释一下我是否需要 & 在第一个代码片段中
- OpenGL 片段着色器未在英特尔 HD 4000 显卡上编译
- 帧缓冲纹理变为白色(片段着色器不会影响它)
- 如何在 c++ 中检查连续片段中数字被 11 整除
- 提取狮身人面像文档中的C++代码片段
- 为什么此代码片段有效?如何取消引用空点?
- 将顶点位置从顶点传递到片段着色器 - 仅在使用 Nsight 进行调试时有效
- 无法在这个基本的Qt代码片段中找到错误,但我被告知它肯定存在?
- 使用片段着色器写入 1D 纹理后从 1D 纹理读回不起作用
- 如何在顶点着色器中使用VBO数据作为位置数据,在片段着色器中使用统一数据作为颜色数据
- 这个代码片段中会发生死锁吗?为什么
- 同时与两个片段着色器发生碰撞
- 如何优化C 代码的以下片段 - 卷中的零交叉点