如果我有一些指针或类似指针的值打包到SSE或AVX寄存器中,是否有任何特别有效的方法取消引用它们,进入另一个这样的寄存器? (“特别高效”意味着“比仅使用内存更有效”。)是否有任何方法可以取消引用它们而无需将寄存器的中间副本写入内存?
编辑以澄清:这意味着,假设32位指针和SSE,使用XMM寄存器的四个部分一次索引到四个任意存储区,并一次将四个结果返回到另一个寄存器。或尽可能接近“立刻”。 (/编辑)
Edit2:感谢PaulR的回答我想我正在寻找的术语是“聚集”,因此问题是“在AVX2之前实现系统聚集的最佳方法是什么?”。
我认为没有这方面的指示,因为......好吧,就我所知,似乎并不存在,无论如何它似乎根本不是SSE的设计。< / p>
(“类指针值”意味着类似于假装成堆的数组的整数索引;机械上非常不同但在概念上是相同的。例如,如果想要使用32位甚至16位值,无论本机指针大小如何,都可以在寄存器中包含更多值。)
我可以想到为什么人们可能想要这样做的两个可能原因:
认为将SSE寄存器用于通用...的东西可能很有意思,可能有四个相同的“线程”处理可能完全不相关/不连续的数据,“垂直切换”寄存器“而不是”水平“(即代替他们设计使用的方式)。
如果由于某种原因(可能不是很好的话)构建类似romcc的东西,那么就不想在内存中写入任何东西,因此需要更多的寄存器存储。
这可能听起来像XY problem,但事实并非如此,只是好奇/愚蠢。一旦拿到锤子,我就会去寻找钉子。
答案 0 :(得分:1)
问题并不完全清楚,但是如果你想取消引用向量寄存器元素,那么可能对你有帮助的唯一指令就是AVX2收集的负载,例如: _mm256_i32gather_epi32
等。请参阅Intel Intrinsics Guide的AVX2部分。
SYNOPSIS
__m256i _mm256_i32gather_epi32 (int const* base_addr, __m256i vindex, const int scale)
#include "immintrin.h"
Instruction: vpgatherdd ymm, vm32x, ymm
CPUID Flag : AVX2
DESCRIPTION
Gather 32-bit integers from memory using 32-bit indices. 32-bit elements are loaded from addresses starting at base_addr and offset by each 32-bit element in vindex (each index is scaled by the factor in scale). Gathered elements are merged into dst. scale should be 1, 2, 4 or 8.
OPERATION
FOR j := 0 to 7
i := j*32
dst[i+31:i] := MEM[base_addr + SignExtend(vindex[i+31:i])*scale]
ENDFOR
dst[MAX:256] := 0
答案 1 :(得分:1)
因此,如果我理解正确,你的标题会产生误导,你真的想:
右?
那太难了。有点奇怪,但我对此很好。
假设允许疯狂的技巧,我建议自我修改代码:(未经测试)
pextrb eax, xmm?, ? // question marks are the position of the pointer
mov edx, eax
shr eax, 1
and eax, 0x38
add eax, 0xC0 // C0 makes "hack" put its result in eax
mov [hack+4], al // xmm{al}
and edx, 15
mov [hack+5], dl // byte [dl] of xmm reg
call hack
pinsrb xmm?, eax, ? // put value back somewhere
...
hack:
db 66 0F 3A 14 00 00 // pextrb ?, ? ,?
ret
据我所知,你不能使用完整的ymm
寄存器(但是?)。通过更多努力,您可以将其扩展到xmm8
- xmm15
。它可以轻松调整到其他指针&#34;尺寸和其他元素尺寸。