1

我想知道将 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;
}
4

1 回答 1

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

#include <stdalign.h>
alignas(32) 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 性能,大约为对齐情况的四分之一。

我在这里分享是因为有人说对齐/未对齐存储之间没有区别,除了调试!

于 2017-03-15T20:23:20.117 回答