c - 将 256 位 AVX vector 存储为无符号长整数的最佳方法

标签 c vector avx avx2 avx512

我想知道将 256 位长的 AVX vector 存储为 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;
}

最佳答案

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

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

}

因此,您正在寻找的最佳指令是 _mm256_storeu_si256 此指令将 __m256i vector 存储到未对齐的地址,如果您的数据已对齐,您可以使用 _mm256_store_si256。要查看您的 vector 值,您可以使用此函数:

#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 让您选择要存储到内存中的元素。当您想要存储具有更多选项的 vector 以将元素存储到内存或不更改内存值时,此指令很有用。

我正在阅读 Intel 64 和 IA-32 架构优化引用手册 (248966-032),2016 年,第 410 页,有趣地发现未对齐的存储仍然是性能 killer 。 p>

11.6.3 Prefer Aligned Stores Over Aligned Loads

There are cases where it is possible to align only a subset of the processed data buffers. In these cases, aligning data buffers used for store operations usually yields better performance than aligning data buffers used for load operations. Unaligned stores are likely to cause greater performance degradation than unaligned loads, since there is a very high penalty on stores to a split cache-line that crosses pages. This penalty is estimated at 150 cycles. Loads that cross a page boundary are executed at retirement. In Example 11-12, unaligned store address can affect SAXPY performance for 3 unaligned addresses to about one quarter of the aligned case.

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

关于c - 将 256 位 AVX vector 存储为无符号长整数的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42763487/

相关文章:

c++ - 使用迭代器获取 vector 的索引

c++ - 从四个 __m128i 变量的 64 高位或低位初始化 __m256i

x86 - _mm_alignr_epi8 (PALIGNR) 在 AVX2 中等效

c++ - 从 __m256 选择元素子集?

c - C 函数 time() 如何处理小数秒?

c - 将空格添加回我的汇编程序中

c - 从 C 例程打印变量

从 C 中的 Contiki uip 地址构造新的 IPv6 地址

java - 在 Java 上搜索 Vector 内的属性

c++ - 尝试将元组推回 const vector 时出错