2

我正在尝试有效地将内存中不同位置的 16 个 32 位值收集到 mm512i 向量中,以进行进一步的 32 位 SIMD 操作:

假设我有 16 个 32 位数据的缓冲区,其 16 个指针位于数组 c 中:

uint32_t buffer0[100];
uint32_t buffer1[100];
...
uint32_t buffer15[100];
uint32_t* c = [buffer0, buffer1, ... buffer15];

我想用这 16 个数组的内容(开始的第一个单词)初始化 _m512i 向量,并有一种有效的方法来移动我想使用 16*32 位 SIMD 操作处理的缓冲区数据。到目前为止,我已经写了以下内容:

uint64_t base = c[0];
__m512i vindex0 = _mm512_setr_epi64 ((uint64_t)c[0],
                                     (uint64_t)c[1],
                                     (uint64_t)c[2],
                                     (uint64_t)c[3],
                                     (uint64_t)c[4],
                                     (uint64_t)c[5],
                                     (uint64_t)c[6],
                                     (uint64_t)c[7])
//create a list of offset from buffer0, hopefully fitting on 32 bits:
vindex0 = _mm512_sub_epi64(vindex0,_mm512_set1_epi64(base));

__m512i vindex1 = _mm512_setr_epi64 ((uint64_t)c[8],
                                     (uint64_t)c[9],
                                     (uint64_t)c[10],
                                     (uint64_t)c[11],
                                     (uint64_t)c[12],
                                     (uint64_t)c[13],
                                     (uint64_t)c[14],
                                     (uint64_t)c[15]);
//create a list of offset from buffer0, hopefully fitting on 32 bits
vindex1 = _mm512_sub_epi64(vindex1,_mm512_set1_epi64(base)); 

//now concatenate the 2 256 vectors of 8 32 address each into a 512b vector:
__m512i vindex = __MM512_CONCAT(_mm512_cvtsepi64_epi32(vindex0), 
                                _mm512_cvtsepi64_epi32(vindex1)); 

我的主要问题当然是找到正确的内置函数来执行上面的连接(我称之为 __MM512_CONCAT)。但更一般地说,我想知道这是否是正确的方法。这要求我的所有缓冲区都位于 4GB 地址空间中(如果使用_mm512_i32gather_epi32()scale 参数并接受缓冲区对齐要求,则为 4GB 的倍数)。

为了进一步移动我的数据,我计划执行以下操作:

__m512i increment = _mm512_set1_epi32 ((uint32_t)sizeof(uint32_t));
vindex = _mm512_add_epi32(vindex, increment);
//next 32b-word in each buffer:
data = _mm512_i32gather_epi32(vindex, base, 0);                                                                         

如果这不是从分散的地址空间初始化 16x32 (=512) 位向量的正确方法,他们应该怎么做?如果是,那么连接 256b 向量的正确方法是什么,以及在增量时间或增量时间将我的 64 位偏移量转换为 32 位时如何进行优雅的饱和度检查_mm512_cvtsepi64_epi32()

4

0 回答 0