我正在尝试使用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进行编译。
提前感谢您的帮助! - 贾斯汀
答案 0 :(得分:4)
您获得了正确的结果。请参阅Intel® Advanced Vector Extensions Programming Reference,第320-333页。
几乎没有AVX指令跨越128位边界,大多数指令分别作为每个低和高128位的SSE指令。非常不幸。
答案 1 :(得分:3)
表现如预期。
要获得[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位。