ARM NEON 图像转换优化
Posted
技术标签:
【中文标题】ARM NEON 图像转换优化【英文标题】:ARM NEON Optimization for image transformation 【发布时间】:2013-10-18 04:56:23 【问题描述】:我正在应用 NV12 视频转换,它会随机播放视频的像素。在 ARM 设备(如 Google Nexus 7 2013)上,使用以下 C 代码,在 1024x512 区域的 30fps 时性能相当糟糕:
* 仅在视频开头进行一次预处理 *
//Temporary tables for the destination
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
toY[i][j] = j * width + i;
toUV[i][j] = j / 2 * width + ((int)(i / 2)) * 2;
//Temporary tables for the source
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
fromY[i][j] = funcY(i, j) * width + funcX(i, j);
fromUV[i][j] = funcY(i, j) / 2 * width + ((int)(funcX(i, j) / 2)) * 2;
* 在每一帧完成的过程 *
for (j = 0; j < height; j++)
for (i = 0; i < width; i++)
destY[ toY[i][j] ] = srcY[ fromY[i][j] ];
if ((i % 2 == 0) && (j % 2 == 0))
destUV[ toUV[i][j] ] = srcUV[ fromUV[i][j] ];
destUV[ toUV[i][j] + 1 ] = srcUV[ fromUV[i][j] + 1 ];
虽然只计算了一次,但funcX/Y是一个相当复杂的转换,所以优化这部分不是很容易。
还有没有办法用给定的“从”表来固定在每一帧计算的双循环?
【问题讨论】:
最好不要使用任何表作为索引——试着一直做算术。内存带宽比 CPU 更稀缺。也许您可以更清楚地告诉您如何遍历图像,并且人们可以就如何改进给您更好的想法。 【参考方案1】:您创建了 4 个 8 倍于原始图像的查找表?
你在最里面的循环中放了一个不必要的 if 语句?
交换 i 和 j 怎么样?
老实说,你的问题应该用 [c] 来标记,而不是从 arm、neon 或 image-processing 开始。
由于您没有展示 funcY 和 funcX 的作用,我能给出的最佳答案是跟随。 (性能飙升。这是非常基础的东西)
//Temporary tables for the source
pTemp = fromYUV;
for (j = 0; j < height; j+=2)
for (i = 0; i < width; i+=2)
*pTemp++ = funcY(i, j) * width + funcX(i, j);
*pTemp++ = funcY(i+1, j) * width + funcX(i+1, j);
*pTemp++ = funcY(i, j) / 2 * width + ((int)(funcX(i, j) / 2)) * 2;
for (i = 0; i < width; i+=2)
*pTemp++ = funcY(i, j+1) * width + funcX(i, j+1);
*pTemp++ = funcY(i+1, j+1) * width + funcX(i+1, j+1);
* Process done at each frame *
pTemp = fromYUV;
pTempY = destY;
pTempUV = destUV;
for (j = 0; j < height; j+=2)
for (i = 0; i < width; i+=2)
*pTempY++ = srcY[*pTemp++];
*pTempY++ = srcY[*pTemp++];
*pTempUV++ = srcUV[*pTemp++];
for (i = 0; i < width; i+=2)
*pTempY++ = srcY[*pTemp++];
*pTempY++ = srcY[*pTemp++];
你应该避免(如果可能的话):
访问多个内存区域 随机内存访问 循环中的 if 语句你犯的最严重的罪行是 i 和 j 的顺序。 (你不需要开始)
如果您访问坐标 x 和 y 处的像素,则它是 pixel = image[y][x] 和 NOT image[x][y]
【讨论】:
以上是关于ARM NEON 图像转换优化的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ARM NEON 中将 uint8x8_t 加载到 float32x4 中?
二进制图像上的快速像素计数 - ARM neon 内在函数 - iOS 开发