有效地矢量化图像块处理?

时间:2016-10-10 19:49:54

标签: c++ image sse simd neon

我很好奇当我逐块处理图像时最有效的方法是什么。

那时,我应用了一些矢量化技术,例如我从8x8块读取一行像素(每行8个像素,每个8位深度)。但是,由于现代处理器支持128/256位向量操作,我认为从图像块加载两行像素可以提高代码速度。

但问题是,内存中的图像(例如16x16图像,包含4个8x8块)连续地从第一个像素存储到最后一个像素。加载一个8像素的行很容易,但是我应该如何操作指针或对齐图像数据以便我可以一起加载2行?

我认为这个数字可以清楚地说明我的问题: pixels' address in a image

因此,当我们一起加载8个像素(一行)时,我们只需将初始指针位置的8个字节数据加载1个指令。当我们加载第二行时,我们只需向指针添加9并加载第二行。

所以,问题是,是否有任何方法可以将这两行(16个像素)从初始指针位置加载到一起?

谢谢!

1 个答案:

答案 0 :(得分:1)

要使每一行对齐,您可以填充每行的末尾。编写代码以支持比行之间的步幅更短的图像宽度,使您的算法可以处理图像的子集。

此外,您实际上并不需要将所有内容对齐以使SIMD正常运行。连续就足够了。大多数SIMD指令集(SSE,NEON等)都有未对齐的加载指令。根据具体实施情况,可能没有太大的惩罚。

您不会将两个不同的行加载到同一SIMD向量中。例如,要使用AVX2 VPSADBW执行8x8 SAD(绝对差值之和),每个32字节负载将从四个不同8x8块的一行中获取数据。但是没关系,你只需要用它来并行生成四个8x8 SAD结果,而不是浪费大量时间来进行单个8x8 SAD。

例如,Intel's MPSADBW tutorial显示了如何使用C和Intel的SSE内在函数实现4x4,8x8和16x16块的详尽运动搜索。显然,实际的MPSADBW指令实际上并不值得在实践中使用,因为它比PSADBW慢,并且你可以通过x264使用的顺序消除穷举搜索更快地获得相同的结果(x264开发人员在{{3}中提到)关于SSE4.1是否会帮助x264。)

Dark Shikari博客档案中的一些SIMD编程博客文章:x264开发者日记: