我有这样的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
是Microsoft特定的指令,用于从长AVX寄存器中提取单个浮点数。但是我可以用gcc / linux来做同样的事情吗?
答案 0 :(得分:4)
GCC可以用C语言索引向量,但不能用C ++索引。您可以考虑将代码的一小部分重写为C。
另一种选择是明确使用随机数,提取和转换内在函数 - _mm256_shuffle_pd
,_mm256_extractf128_pd
,_mm_cvtsd_f64
。
答案 1 :(得分:1)
关注@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);
}