使用AVX / AVX2内部函数,我可以使用以下方法收集8个值的集合:1、2或4个字节的整数,或4个字节的浮点数:
__ mm256_i32gather_epi32()
_ mm256_i32gather_ps()
但是目前,我正在加载在nvidia GPU上生成并存储为FP16值的数据。如何对这些值进行矢量化加载?
到目前为止,我发现了_ mm256_cvtph_ps() intrinsic。
但是,该内在函数的输入是__ m128i值,而不是__ m256i值。
查看《英特尔内部技术指南》,我没有看到将8个值存储到_mm128i寄存器中的收集操作?
如何将FP16值收集到__m256寄存器的8个通道中?是否可以将它们作为2个字节的短裤向量加载到__m256i中,然后以某种方式将其减小为__m128i值以传递到转换固有函数中?如果是这样,我还没有发现内在函数可以做到这一点。
UPDATE
我按照@ peter-cordes的建议尝试了演员表,但是我从中得到虚假的结果。另外,我不知道该怎么做?
我的2字节int值在__m256i中存储为:
0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX
所以我怎么能简单地投射到__m128i,需要将其紧密包装为
XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
演员会这样做吗?
我当前的代码:
__fp16* fielddensity = ...
__m256i indices = ...
__m256i msk = _mm256_set1_epi32(0xffff);
__m256i d = _mm256_and_si256(_mm256_i32gather_epi32(fielddensity,indices,2), msk);
__m256 v = _mm256_cvtph_ps(_mm256_castsi256_si128(d));
但是结果似乎不是正确形成的8个值。我认为每个第二个对我来说都是假的?
确实没有16位值的收集指令,因此您需要收集32位值并忽略其中一半(并确保您不会意外地从无效内存中读取)。另外,_mm256_cvtph_ps()
需要低128位通道中的所有输入值,但不幸的是,没有通道交叉的16位随机播放(直到AVX512)。