将256位AVX向量存储到无符号长整数的最佳方法

时间:2017-03-13 12:18:31

标签: c vector avx avx2 avx512

我想知道将256位长的AVX向量存储到4个64位无符号长整数中的最佳方法是什么。根据网站https://software.intel.com/sites/landingpage/IntrinsicsGuide/中写的函数,我只能想出使用maskstore(下面的代码)来做到这一点。但这是最好的方法吗?或者还有其他方法吗?

#include <immintrin.h>
#include <stdio.h>

int main() {

    unsigned long long int i,j;
    unsigned long long int bit[32][4];//256 bit random numbers
    unsigned long long int bit_out[32][4];//256 bit random numbers for test

    for(i=0;i<32;i++){ //load with 64 bit random integers
        for(j=0;j<4;j++){
            bit[i][j]=rand();
            bit[i][j]=bit[i][j]<<32 | rand();
        }
    }

//--------------------load masking-------------------------
    __m256i v_bit[32];
    __m256i mask;
    unsigned long long int mask_ar[4];
    mask_ar[0]=~(0UL);mask_ar[1]=~(0UL);mask_ar[2]=~(0UL);mask_ar[3]=~(0UL);
    mask = _mm256_loadu_si256 ((__m256i const *)mask_ar);
//--------------------load masking ends-------------------------

//--------------------------load the vectors-------------------
    for(i=0;i<32;i++){

        v_bit[i]=_mm256_loadu_si256 ((__m256i const *)bit[i]);

    }
//--------------------------load the vectors ends-------------------

//--------------------------extract from the vectors-------------------
    for(i=0;i<32;i++){

        _mm256_maskstore_epi64 (bit_out[i], mask, v_bit[i]);
    }
//--------------------------extract from the vectors end-------------------

    for(i=0;i<32;i++){ //load with 64 bit random integers
        for(j=0;j<4;j++){
            if(bit[i][j]!=bit_out[i][j])
                printf("----ERROR----\n");
        }
    }

  return 0;
}

1 个答案:

答案 0 :(得分:1)

正如其他人在评论中所说,在这种情况下你不需要使用掩码存储。以下循环在程序中没有错误

for(i=0;i<32;i++){
   _mm256_storeu_si256 ((__m256i const *) bit_out[i], v_bit[i]);

}

因此,您要查找的最佳指令是_mm256_storeu_si256如果您的数据已对齐,此指令会将__m256i向量存储到未对齐的地址,您可以使用_mm256_store_si256。要查看矢量值,您可以使用此功能:

unsigned long long int tempu64[4];
void printVecu64(__m256i vec)
{
    _mm256_store_si256((__m256i *)&tempu64[0], vec);
    printf("[0]= %u, [1]=%u, [2]=%u, [3]=%u \n\n", tempu64[0],tempu64[1],tempu64[2],tempu64[3]) ;

}

_mm256_maskstore_epi64允许您选择要存储到内存中的元素。当您想要存储具有更多选项的向量以将元素存储到存储器或不更改存储器值时,此指令非常有用。

我正在阅读 Intel 64和IA-32架构优化参考手册(248966-032),2016,第410页。并且有趣地发现未对齐的商店仍然是性能杀手。

  

11.6.3首选对齐载荷上的对齐商店

     

有些情况下,只能对齐一部分   处理数据缓冲区。在这些情况下,对齐用于的数据缓冲区   存储操作通常比对齐数据产生更好的性能   用于加载操作的缓冲区。未对齐的商店可能会导致   比未对齐的负载更大的性能下降,因为有一个   对于跨越页面的拆分缓存行,存储的惩罚非常高。   此惩罚估计为 150个周期。跨页面的载荷   边界在退休时执行。在例11-12中,未对齐的商店   地址可以影响3个未对齐地址的SAXPY性能   大约四分之一的对齐案例。

我在这里分享是因为有些人说在对齐/未对齐的商店之间没有区别,除了在debuging中!