首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于AVX本质的压缩掩码

基于AVX本质的压缩掩码
EN

Stack Overflow用户
提问于 2014-05-23 12:28:57
回答 2查看 2.5K关注 0票数 5

我想结合两个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_0a_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为止的一切。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-23 13:27:12

看起来您可以利用这样一个事实:在单精度和双精度中,所有1s的位模式都是NaN,同样,在这两种情况下,所有0的位模式都是0.0。因此,要将两个双掩码矢量打包成一个浮动矢量,可以这样做:

代码语言:javascript
复制
 __m256 v = _mm256_set_m128(_mm256_cvtpd_ps(v0), _mm256_cvtpd_ps(v1));

请注意,如果您没有_mm256_set_m128,则可以将其定义为:

代码语言:javascript
复制
#define _mm256_set_m128(va, vb) \
        _mm256_insertf128_ps(_mm256_castps128_ps256(vb), va, 1)

下面是一个演示:

代码语言:javascript
复制
#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;
}

测试:

代码语言:javascript
复制
$ 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
票数 4
EN

Stack Overflow用户

发布于 2014-05-25 04:38:35

在下面的代码中,function1()执行操作。主程序提供样本数据并打印结果。样本数据的模糊部分是要省略的上半部分。样本数据的其余数据包含唯一的模式。程序输出是:

代码语言:javascript
复制
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有限的交叉车道能力使得解决方案相对复杂。

代码语言:javascript
复制
#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;
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23829290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档