Неожиданный результат от AVX _m256_unpack * _ps распаковать внутреннюю - PullRequest
4 голосов
/ 14 июля 2011

Я пытаюсь использовать внутренние инструкции распаковки AVX _m256_unpacklo_ps и _m256_unpackhi_ps, чтобы чередовать 16 значений с плавающей запятой. Результаты, которые я получаю, странные, либо потому, что я не понимаю, как распаковка должна работать в AVX, либо потому, что что-то работает не так, как должно.

Что я вижу, так это то, что когда я пытаюсь, например, распаковать плавающие младшие разряды из двух векторов, v1 и v2, в третий, v3, я вижу следующее:

, если v1 [a b c d e f g h] и v1 [i j k l m n o p]

затем v3 = _m256_unpacklo_ps(v1, v2) приводит к [a i b j e m f n]

когда я ожидал, что v3 выдаст [a i b j c k d l]

Я ошибаюсь в своих ожиданиях или использую это неправильно? Или что-то не работает?

Некоторые тестовые коды:

#include <immintrin.h>
#include <iostream>

int main()
{

  float output[16], input1[8], input2[8];
  __m256 vec1, vec2, vec3, vec4;

  vec1 = _mm256_set_ps(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f);
  vec2 = _mm256_set_ps(9.0f, 10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f);

  _mm256_store_ps(input1, vec1);
  _mm256_store_ps(input2, vec2);

  vec3 = _mm256_unpacklo_ps(vec1, vec2);
  vec4 = _mm256_unpackhi_ps(vec1, vec2);

  _mm256_store_ps(output, vec3);
  _mm256_store_ps(output + 8, vec4);

  std::cout << "interleaving:" << std::endl;
  for (unsigned i = 0; i < 8; ++i)
    std::cout << input1[i] << " ";
  std::cout << std::endl;

  std::cout << "with:" << std::endl;
  for (unsigned i = 0; i < 8; ++i)
    std::cout << input2[i] << " ";
  std::cout << std::endl;

  std::cout << "= " << std::endl;
  for (unsigned i = 0; i < 16; ++i)
    std::cout << output[i] << " ";
  std::cout << std::endl;
}

Я использую gcc 4.5.2 для компиляции.

Заранее спасибо за любую помощь! - Джастин

Ответы [ 2 ]

4 голосов
/ 14 июля 2011

Вы получаете правильный результат.См. Справочник по программированию Intel® Advanced Vector Extensions , стр. 320-333.

Практически никакие инструкции AVX не пересекают 128-битную границу, большинство из них работают как инструкции SSE для каждого младшего и старшего 128-битного в отдельности.Очень неудачно.

3 голосов
/ 02 декабря 2012

Это ведет себя как ожидалось.

Чтобы получить [a i b j c k d l], вам нужно использовать:

A = unpacklo_ps(v1,v2)

B = unpackhi_ps(v1,v2) и затем используйте

C=_mm256_permute2f128_ps(A,B,0x20),

для получения желаемых 128 битов от них обоих.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...