c - 在 AVX2 vector 中加载 16 位整数?

标签 c vector avx2

我是 AVX 编程新手。我想加载具有 16 个短整数或 16 位值的 __m256 vector ,但我无法这样做。

这是我的尝试。它给出了以下错误:

incompatible types when initializing type ‘__m256’ using type ‘int’ __m256 result = _mm256_load_epi16((__m256*)&int_array);

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

int main() {
  int i;

  short int int_array[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};


  __m256 result = _mm256_load_epi16((__m256*)&int_array);

  short int* res = (short int*)&result;
  printf("%d %d %d %d %d %d %d %d\n", res[0], res[1], res[2], res[3], res[4], res[5], res[6], res[7]);

  return 0;
}

最佳答案

__m256i integer_vector = _mm256_load_si256((__m256*)int_array);

三个问题:

  • 您忽略了编译器对 _mm256_load_epi16 的隐式声明警告,该警告不存在。这就是为什么它提示从 int 初始化 __m256i
  • int_array 已经是指向第一个元素的指针。 &int_array 是指向指针的指针。你不想加载那个。
  • __m256 是一个包含 8 个 float 的 vector 。你想要 __m256i。 (内在函数区分整数、 float 和 double vector 。这与 asm 指令匹配:使用整数 vector 运算的结果作为 FP vector 运算的输入(反之亦然)会导致额外的旁路延迟延迟。这停止你不会随意/不小心对整数数据使用 FP 洗牌。有时它仍然是值得的,这就是为什么存在像 __m128 _mm_castsi128_ps(__m128i) 这样的函数。)

对于具有不同整数元素大小的加载/存储,没有单独的内在函数。这就是为什么您总是必须将那些烦人的转换写入 (__m256i*) 的原因。 (AVX512 内在函数将采用 void* args,这是一个更好的设计 IMO。)

英特尔的内部函数查找器 ( https://software.intel.com/sites/landingpage/IntrinsicsGuide/ ) 将帮助您找到所需的函数。另见 标记 wiki 以获取指南,以及 标签 wiki 有好东西。


第四个问题:您没有对齐数组,因此使用对齐加载内在函数是不安全的。您可以改用 loadu 内部函数。


第五题:

short int* res = (short int*)&result; 是个坏主意。不要将指针别名指向 vector 。将 vector 指针别名到数组上是可以的,因为 __m256i 是用“may alias”属性定义的。但是取消引用 (short int*)&result 是 C/C++ 未定义的行为,并且不会做你想做的事(理论上或实践中)。

存储到临时数组,使用 _mm_extract_epi16,或使用 union 进行类型双关。

关于c - 在 AVX2 vector 中加载 16 位整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39413328/

相关文章:

c - 读入未知大小的字符数组

c - 具有位域的结构的内存布局

c++ - 这个 vector 编码有什么问题?(初学者)

c - 使用 strtok() 的正确方法;

c - 查找除以空格的单词

Java 从二维数组制作 vector 。

c++ - 将SSE矩阵 vector 乘法代码转换为AVX

c++ - AVX计算精度

c++ - 出于某种原因,串行代码比 SIMD 代码运行得更快

c - 我无法在文件中添加全名,只能添加一个字符,那么如何在文件中添加完整字符串?