【发布时间】:2017-02-14 13:08:24
【问题描述】:
我是 SIMD 内部函数的初学者,所以我会提前感谢大家的耐心等待。我有一个应用程序涉及无符号字节的绝对差异比较(我正在处理灰度图像)。
我尝试了 AVX、更现代的 SSE 版本等,但最终认为 SSE2 似乎足够并且对单个字节的支持最多 - 如果我错了,请纠正我。
我有两个问题:首先,加载 128 位寄存器的正确方法是什么?我想我应该传递与 128 的倍数对齐的负载内在数据,但这是否适用于像这样的二维数组代码:
greys = aligned_alloc(16, xres * sizeof(int8_t*));
for (uint32_t x = 0; x < xres; x++)
{
greys[x] = aligned_alloc(16, yres * sizeof(int8_t*));
}
(上面的代码假设 xres 和 yres 相同,并且是 2 的幂)。这会变成内存中的线性、不间断的块吗?那么,当我循环时,我可以继续将地址(将它们增加 128)传递给 SSE2 加载内在函数吗?或者像这样的二维数组需要做一些不同的事情吗?
我的第二个问题:一旦我完成了所有的向量处理,我到底如何从 __m128i 中提取修改后的字节?查看英特尔内部指南,将向量类型转换为标量类型的指令很少见。我找到的最接近的是 int _mm_movemask_epi8 (__m128i a),但我不太明白如何使用它。
哦,还有第三个问题——我假设_mm_load_si128 只加载有符号字节?而且我找不到任何其他字节加载函数,所以我猜你应该从每个中减去 128 并在以后考虑它?
我知道这些是 SIMD 专家的基本问题,但我希望这个问题对像我这样的初学者有用。如果你认为我对应用程序的整个方法是错误的,或者我最好使用更现代的 SIMD 扩展,我很想知道。我只想谦虚地警告我从未使用过汇编,所有这些琐碎的东西需要大量的解释才能帮助我。
尽管如此,我很感激任何可用的澄清。
以防万一:我的目标是低功耗 i7 Skylake 架构。但最好让应用程序也能在更旧的机器上运行(因此是 SSE2)。
【问题讨论】:
标签: c image-processing vectorization simd sse2