有效地矢量化图像块处理?
Vectorise image block processing efficiently?
我很好奇当我逐块处理图像时,最有效的方法是什么。
在那一刻,我应用了一些矢量化技术,例如我从一个 8x8 块中读取一行像素(一行 8 个像素,每个 8 位深度)。但由于现代处理器支持128/256位矢量运算,我认为从图像块加载两行像素可以提高代码速度。
但问题是,一张图片(比如16x16的图片,包含4个8x8的块)在内存中是从第一个像素到最后一个像素连续存储的。一个8像素行的加载很容易,但是我应该如何操作指针或对齐图像数据才能同时加载2行?
我觉得这个图可以很清楚的说明我的问题:
pixels' address in a image
因此,当我们一起加载8个像素(一行)时,我们只需通过一条指令从初始指针位置加载8个字节的数据。当我们加载第二行时,我们只需将指针加 9 并加载第二行。
所以,问题是,有什么方法可以从初始指针位置一起加载这两行(16 像素)?
谢谢!
要使每行对齐,您可以填充每行的末尾。编写代码以支持比行间步幅更短的图像宽度,让您的算法可以处理图像的子集。
此外,您实际上不需要对齐所有内容才能使 SIMD 正常工作。连续就足够了。大多数 SIMD 指令集(SSE、NEON 等)都有未对齐的加载指令。根据具体实施情况,可能不会有太大的惩罚。
您不会将两个不同的行加载到同一个 SIMD 向量中。例如,要使用 AVX2 VPSADBW 执行 8x8 SAD(绝对差之和),每个 32 字节加载将从一行四个不同的 8x8 块中获取数据。但这没关系,您只需使用它并行生成四个 8x8 SAD 结果,而不是浪费大量时间洗牌来做一个 8x8 SAD。
例如,Intel's MPSADBW tutorial shows how to implement an exhaustive motion search for 4x4, 8x8, and 16x16 blocks, with C and Intel's SSE intrinsics. Apparently the actual MPSADBW instruction isn't actually worth using in practice, though, because it's slower than PSADBW and you can get identical results faster with a sequential elimination exhaustive search, as used by x264 (and mentioned by x264 developers in this forum thread关于 SSE4.1 是否对 x264 有帮助。)
来自 Dark Shikari 博客档案的一些 SIMD 编程博文:x264 开发者日记:
- Cacheline splits, take two:使用 PALIGNR 或其他技术为运动搜索设置未对齐的输入
- A curious SIMD assembly challenge: the zigzag
我很好奇当我逐块处理图像时,最有效的方法是什么。
在那一刻,我应用了一些矢量化技术,例如我从一个 8x8 块中读取一行像素(一行 8 个像素,每个 8 位深度)。但由于现代处理器支持128/256位矢量运算,我认为从图像块加载两行像素可以提高代码速度。
但问题是,一张图片(比如16x16的图片,包含4个8x8的块)在内存中是从第一个像素到最后一个像素连续存储的。一个8像素行的加载很容易,但是我应该如何操作指针或对齐图像数据才能同时加载2行?
我觉得这个图可以很清楚的说明我的问题: pixels' address in a image
因此,当我们一起加载8个像素(一行)时,我们只需通过一条指令从初始指针位置加载8个字节的数据。当我们加载第二行时,我们只需将指针加 9 并加载第二行。
所以,问题是,有什么方法可以从初始指针位置一起加载这两行(16 像素)?
谢谢!
要使每行对齐,您可以填充每行的末尾。编写代码以支持比行间步幅更短的图像宽度,让您的算法可以处理图像的子集。
此外,您实际上不需要对齐所有内容才能使 SIMD 正常工作。连续就足够了。大多数 SIMD 指令集(SSE、NEON 等)都有未对齐的加载指令。根据具体实施情况,可能不会有太大的惩罚。
您不会将两个不同的行加载到同一个 SIMD 向量中。例如,要使用 AVX2 VPSADBW 执行 8x8 SAD(绝对差之和),每个 32 字节加载将从一行四个不同的 8x8 块中获取数据。但这没关系,您只需使用它并行生成四个 8x8 SAD 结果,而不是浪费大量时间洗牌来做一个 8x8 SAD。
例如,Intel's MPSADBW tutorial shows how to implement an exhaustive motion search for 4x4, 8x8, and 16x16 blocks, with C and Intel's SSE intrinsics. Apparently the actual MPSADBW instruction isn't actually worth using in practice, though, because it's slower than PSADBW and you can get identical results faster with a sequential elimination exhaustive search, as used by x264 (and mentioned by x264 developers in this forum thread关于 SSE4.1 是否对 x264 有帮助。)
来自 Dark Shikari 博客档案的一些 SIMD 编程博文:x264 开发者日记:
- Cacheline splits, take two:使用 PALIGNR 或其他技术为运动搜索设置未对齐的输入
- A curious SIMD assembly challenge: the zigzag