[C++] AVXレジスタからデータを取り出す方法は?


Answers

AVX(つまりAVX2がない)しか持っていないと仮定すると、次のようなことができます:

float extract_float(const __m128 v, const int i)
{
    float x;
    _MM_EXTRACT_FLOAT(x, v, i);
    return x;
}

void print(const __m128 v)
{
    print(extract_float(v, 0));
    print(extract_float(v, 1));
    print(extract_float(v, 2));
    print(extract_float(v, 3));
}

void print(const __m256 v)
{
    print(_mm256_extractf128_ps(v, 0));
    print(_mm256_extractf128_ps(v, 1));
}

しかし、おそらく私は組合を使うだけだろうと思う:

union U256f {
    __m256 v;
    float a[8];
};

void print(const __m256 v)
{
    const U256f u = { v };

    for (int i = 0; i < 8; ++i)
        print(u.a[i]);
}
Question

MSVC 2013とAVX 1を使用して、私はレジスタに8つの浮動小数点数を持っています:

__m256 foo = mm256_fmadd_ps(a,b,c);

今私はすべての8つの浮動inline void print(float) {...}を呼びたいと思います。 インテル ®AVXの侵入によって、これはかなり複雑になりそうです。

print(_castu32_f32(_mm256_extract_epi32(foo, 0)));
print(_castu32_f32(_mm256_extract_epi32(foo, 1)));
print(_castu32_f32(_mm256_extract_epi32(foo, 2)));
// ...

MSVCはこれらの2つの組み込み関数のいずれも持っていません。 確かに、値をメモリに書き戻してそこからロードすることができますが、アセンブリレベルではレジスタを溢れる必要はないと思われます。

ボーナスQ:もちろん書いてみたい

for(int i = 0; i !=8; ++i) 
    print(_castu32_f32(_mm256_extract_epi32(foo, i)))

MSVCでは多くの組み込み関数ループアンローリングを必要としていることを理解していません。 __m256 foo 8x32浮動小数点数にループを書くにはどうしたらいいですか?