【问题标题】:Load 16 bit integers in AVX2 vector?在 AVX2 向量中加载 16 位整数?
【发布时间】:2016-09-09 13:58:55
【问题描述】:

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

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

使用“int”类型初始化“__m256”类型时不兼容的类型 __m256 结果 = _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;
}

【问题讨论】:

  • 尝试用char int_array[16]替换short int int_array[16],用_mm256_load_epi16((__m256*)int_array);替换_mm256_load_epi16((__m256*)&amp;int_array);
  • 我做了更改,虽然我想加载 16 位整数而不是 8 位字符,但得到了同样的错误。

标签: c vector avx2


【解决方案1】:
__m256i integer_vector = _mm256_load_si256((__m256*)int_array);

三个问题:

  • 您忽略了编译器对 _mm256_load_epi16 的隐式声明警告,该警告不存在。这就是为什么它抱怨从 int 初始化 __m256i
  • int_array 已经是指向第一个元素的指针。 &amp;int_array 是指向指针的指针。你不想加载它。
  • __m256 是 8 个浮点数的向量。你想要__m256i。 (内在函数区分整数、浮点数和双精度向量。这与 asm 指令相匹配:使用整数向量运算的结果作为 FP 向量运算的输入(反之亦然)可能会导致额外的旁路延迟延迟。这会停止您可以随意/不小心对整数数据使用 FP shuffle。有时它仍然值得,这就是存在 __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*)&amp;result; 是个坏主意。不要将指针别名到向量上。将向量指针别名到数组上是可以的,因为__m256i 是用“可能别名”属性定义的。但是取消引用 (short int*)&amp;result 是 C/C++ 未定义行为,不会做你想做的事情(理论上或实践中)。

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

【讨论】:

  • 如您所述更改了代码。仍然收到错误,但出现了不同的错误。
  • 警告:从不兼容的指针类型传递“_mm256_load_si256”的参数 1 [默认启用] __m256 结果 =_mm256_load_si256((__m256*)int_array); ^ 包括/immintrin.h:56:0,来自 test.c:1:/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include/avxintrin.h:869:1:注意:预期为 'const __vector(4) long long int *' 但参数类型为 '__vector(8) float *' _mm256_load_si256 (__m256i const *__P) ^
  • 错误:使用“__m256i”类型初始化“__m256”类型时不兼容的类型 __m256 结果 =_mm256_load_si256((__m256*)int_array);
  • @user2764478:注意__m256(浮点向量)和__m256i(整数向量)之间的区别。
  • 更改了 __m256i 结果 =_mm256_load_si256((__m256i*)int_array);编译但给出了分段错误。
猜你喜欢
  • 1970-01-01
  • 2015-04-24
  • 2020-04-07
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 2020-02-29
相关资源
最近更新 更多