在AVX2向量中加载16位整数?

时间:2016-09-09 13:58:55

标签: c vector avx2

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

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

  使用类型'int'初始化类型'__m256'时

不兼容的类型         __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;
}

1 个答案:

答案 0 :(得分:3)

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

三个问题:

  • 您忽略了编译器对_mm256_load_epi16的隐式声明警告,该警告不存在。这就是为什么它抱怨从__m256i初始化int
  • int_array已经是指向第一个元素的指针。 &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*)&result;是一个坏主意。不要将指针别名放在矢量上。将矢量指针别名化到数组上是可以的,因为__m256i定义了“may alias”属性。但解除引用(short int*)&result是C / C ++未定义行为,并且不会做你想要的(理论上或实践中)。

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