我想加载一个256 bit YMM
具有 32 个值的寄存器,每个值长度为 1 个字节。我研究的所有内在函数要么加载double word
,即4 byte
整数,要么加载,quad word
即8 byte
值。如何加载小于这些大小的数据?是否有任何助记符可以做到这一点但没有等效的内在函数?
5 回答
我认为没有办法只收集字节。但在我看来,你需要重新考虑你的问题。这是像素数据吗?例如 RGBA 值?如果是这样,也许您可以更改您的应用程序,使其读取/写入例如 RRRRGGGGBBBB (SSE)。然后你不必收集字节。您可以一次读取 128/256 位,这将是 SIMD 的最有效使用。
请注意,您可以通过使用短 int 操作来提高效率。我的意思是扩展到 16 位并使用 16 位整数 SSE/AVX 指令。
这是一个使用 SSE 的双线性插值示例,它读取四个字节 (RGBA) 的整数,并将它们扩展到 16 位。这比将它们扩展到 32 位要快。SSE3 示例将 RGBARGBARGBARGBA 转换为 RRRRGGGGBBBB。 http://fastcpp.blogspot.no/2011/06/bilinear-pixel-interpolation-using-sse.html
这是一个相当古老的问题,但我认为您可能想要的是采用 32 个字符作为输入参数的AVX
内在函数。__m256i _mm256_set_epi8
您可以简单地将_mm256_load_si256内在函数与强制转换一起使用。该内在函数对应于 VMOVDQA 指令。
这是从内存中读取字节并将它们存储在内存中的代码。
char raw[32] __attribute__ ((aligned (32)));
__v32qi foo = _mm256_loadu_si256( (__m256i*) raw ); // read raw bytes from memory into avx register
_mm256_store_si256( (__m256i*) raw, foo ); // store contents of avx register into memory
如果您愿意,也可以使用 _mm256_loadu_si256 加载未对齐的字节。
你认为这 32 个指针来自哪里?除非您想对 256 字节的查找表进行 32 次并行查找,否则源操作数中实际上没有空间来写入加载所需的地址。
我认为您必须执行四个 8x32 位收集操作,然后合并结果;收集操作支持非对齐访问,因此您可以从调整后的地址加载以在 YMM 寄存器中的正确位置获取目标字节,然后只需与掩码和 OR 进行合并。
没有广播单字节的指令,但是你可以使用_mm256_set1_epi8
intrinsic来达到这个效果。