我想结合两个256位向量(__m256d),其中包含比较操作(如_mm256_cmp_pd)的掩码和256位向量,方法是省略64位双倍的上半部分。
因此,如果在下面的代码中,a_i, b_i, ...是32位字,我有两个256位(4x倍)向量,它们的结构如下:
a_0, a_0, b_0, b_0, c_0, c_0, d_0, d_0和a_1, a_1, b_1, b_1, c_1, c_1, d_1, d_1。
我想要一个256位向量,其结构如下:
a_0, b_0, c_0, d_0, a_1, b_1, c_1, d_1。
我如何有效地利用英特尔的本质来完成这个任务?可用的指令集是到AVX为止的一切。
发布于 2014-05-23 13:27:12
看起来您可以利用这样一个事实:在单精度和双精度中,所有1s的位模式都是NaN,同样,在这两种情况下,所有0的位模式都是0.0。因此,要将两个双掩码矢量打包成一个浮动矢量,可以这样做:
__m256 v = _mm256_set_m128(_mm256_cvtpd_ps(v0), _mm256_cvtpd_ps(v1));请注意,如果您没有_mm256_set_m128,则可以将其定义为:
#define _mm256_set_m128(va, vb) \
_mm256_insertf128_ps(_mm256_castps128_ps256(vb), va, 1)下面是一个演示:
#include <stdio.h>
#include <immintrin.h>
#define _mm256_set_m128(va, vb) \
_mm256_insertf128_ps(_mm256_castps128_ps256(vb), va, 1)
static void printvd(const char * label, __m256d v)
{
int64_t a[4];
_mm256_storeu_pd((double *)a, v);
printf("%s = %lld %lld %lld %lld\n", label, a[0], a[1], a[2], a[3]);
}
static void printvf(const char * label, __m256 v)
{
int32_t a[8];
_mm256_storeu_ps((float *)a, v);
printf("%s = %d %d %d %d %d %d %d %d\n", label, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
}
int main()
{
__m256d v0 = _mm256_set_pd(0.0, 1.0, 2.0, 3.0);
__m256d v1 = _mm256_set_pd(3.0, 2.0, 1.0, 0.0);
__m256d vcmp0 = _mm256_cmp_pd(v0, v1, 1);
__m256d vcmp1 = _mm256_cmp_pd(v1, v0, 1);
__m256 vcmp = _mm256_set_m128(_mm256_cvtpd_ps(vcmp0), _mm256_cvtpd_ps(vcmp1));
printvd("vcmp0", vcmp0);
printvd("vcmp1", vcmp1);
printvf("vcmp ", vcmp);
return 0;
}测试:
$ gcc -Wall -mavx so_avx_test.c && ./a.out
vcmp0 = 0 0 -1 -1
vcmp1 = -1 -1 0 0
vcmp = -1 -1 0 0 0 0 -1 -1发布于 2014-05-25 04:38:35
在下面的代码中,function1()执行操作。主程序提供样本数据并打印结果。样本数据的模糊部分是要省略的上半部分。样本数据的其余数据包含唯一的模式。程序输出是:
v0=A0000000 FFFFFFFF B0000000 FFFFFFFF C0000000 FFFFFFFF D0000000 FFFFFFFF
v1=A0000001 FFFFFFFF B0000001 FFFFFFFF C0000001 FFFFFFFF D0000001 FFFFFFFF
vr=A0000000 B0000000 C0000000 D0000000 A0000001 B0000001 C0000001 D0000001代码使用VS2013使用命令行cl /Ox /arch:AVX sample.c进行测试,gcc 4.9.0使用命令行gcc -O3 -mavx -c sample.c进行测试。
AVX有限的交叉车道能力使得解决方案相对复杂。
#include <intrin.h>
#include <stdint.h>
#include <stdio.h>
//---------------------------------------------------------------------------
static void dump (void *data)
{
uint32_t *d32 = data;
int index;
for (index = 0; index < 8; index++)
printf ("%08X ", d32 [index]);
printf ("\n");
}
//---------------------------------------------------------------------------
static __m256d function1 (__m256d v0, __m256d v1)
{
__m256d tmp0 = _mm256_permute2f128_pd (v0, v1, 0x20);
__m256d tmp1 = _mm256_permute2f128_pd (v0, v1, 0x31);
return _mm256_castps_pd (_mm256_shuffle_ps (_mm256_castpd_ps (tmp0), _mm256_castpd_ps (tmp1), 0x88));
}
//---------------------------------------------------------------------------
int main (void)
{
__m256d v0, v1, vr;
v0 = _mm256_castsi256_pd (_mm256_set_epi32 (0xffffffff, 0xd0000000, 0xffffffff, 0xc0000000, 0xffffffff, 0xb0000000, 0xffffffff, 0xa0000000));
v1 = _mm256_castsi256_pd (_mm256_set_epi32 (0xffffffff, 0xd0000001, 0xffffffff, 0xc0000001, 0xffffffff, 0xb0000001, 0xffffffff, 0xa0000001));
vr = function1 (v0, v1);
printf ("v0="); dump (&v0);
printf ("v1="); dump (&v1);
printf ("vr="); dump (&vr);
return 0;
}https://stackoverflow.com/questions/23829290
复制相似问题