相当于m256_f32的海湾合作委员会

GCC equivalent for m256_f32

本文关键字:委员会 m256 f32 相当于      更新时间:2023-10-16

我有这样的AVX C++代码,在Visual Studio 2010下编译得很好:

#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 做同样的事情呢?

GCC可以用C语言索引向量,但不能用C++索引向量。您可以考虑将代码的小部分重写为 C。

另一种选择是显式使用随机播放、提取和转换内部函数 - _mm256_shuffle_pd_mm256_extractf128_pd_mm_cvtsd_f64

按照@chill,我想出了以下两个解决方案来解决这个特定问题。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);
}