3

Visual Studio 2010 で正常にコンパイルされる、次のような AVX C++ コードがあります。

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

int main() {
    float data[] = {0, 1, 2, 3, 4, 5, 6, 7};
    __m256 ymm0 = _mm256_loadu_ps(data);
    // ..
    float r0 = ymm0.m256_f32[0];
    float r4 = ymm0.m256_f32[4];
    std::cout << r0 << " " << r4 << std::endl;
}

ただし、GCC では次のエラーが発生します。

foo.cpp:8:18: error: request for member ‘m256_f32’ in ‘ymm0’, which is of non-class type ‘__m256 {aka __vector(8) float}’
foo.cpp:9:18: error: request for member ‘m256_f32’ in ‘ymm0’, which is of non-class type ‘__m256 {aka __vector(8) float}’

私はいくつかの調査を行いましたymm0.m256_f32が、長い AVX レジスタから個々のフロートを抽出するための Microsoft 固有の命令のようです。しかし、gcc/linux で同じことを行うには何を使用できますか?

4

2 に答える 2

4

GCCはC言語でベクトルにインデックスを付けることができますが、C++ではできません。コードの小さな部分をCとして書き直すことを検討してください。

もう1つのオプションは、シャッフル、抽出、および変換組み込み関数を明示的に使用することです- _mm256_shuffle_pd、、。_mm256_extractf128_pd_mm_cvtsd_f64

于 2012-11-28T11:52:51.417 に答える
1

@chill に続いて、この特定の問題に対する次の 2 つの解決策を思いつきました。C++ ソリューション:

#include <immintrin.h>
#include <iostream>
int main() {
    float data[] = {0, 1, 2, 3, 4, 5, 6, 7};
    __m256 ymm0 = _mm256_loadu_ps(data);
    // ..
    __m128 low = _mm256_extractf128_ps (ymm0, 0); // extracts lower half
    __m128 high = _mm256_extractf128_ps (ymm0, 1);// extracts upper half
    float r0 = _mm_cvtss_f32 (low);  // extracts lowest float
    float r4 = _mm_cvtss_f32 (high);  // extracts lowest float
    std::cout << r0 << " " << r4 << std::endl;
}

そしてプレーンCのソリューション:

#include <immintrin.h>
#include <stdio.h>

int main() {
    float data[] = {0, 1, 2, 3, 4, 5, 6, 7};
    __m256 ymm0 = _mm256_loadu_ps(data);
    // ..
    float r0 = ymm0[0];
    float r4 = ymm0[4];
    printf("%f, %f", r0, r4);
}
于 2012-11-30T09:25:18.367 に答える