【发布时间】:2013-09-01 23:38:39
【问题描述】:
如何在代码中检查 Visual Studio 编译器是否启用了 SSE/SSE2?
我尝试了#ifdef __SSE__,但没有成功。
【问题讨论】:
标签: c++ visual-studio x86 sse sse2
如何在代码中检查 Visual Studio 编译器是否启用了 SSE/SSE2?
我尝试了#ifdef __SSE__,但没有成功。
【问题讨论】:
标签: c++ visual-studio x86 sse sse2
关于_M_IX86_FP 的一些附加信息。
_M_IX86_FP 仅针对 32 位代码定义。 64 位 x86 代码至少具有 SSE2。您可以使用 _M_AMD64 或 _M_X64 来确定代码是否为 64 位。
#ifdef __AVX2__
//AVX2
#elif defined ( __AVX__ )
//AVX
#elif (defined(_M_AMD64) || defined(_M_X64))
//SSE2 x64
#elif _M_IX86_FP == 2
//SSE2 x32
#elif _M_IX86_FP == 1
//SSE x32
#else
//nothing
#endif
【讨论】:
相关的预处理器宏在每一端都有两个下划线:
#ifdef __SSE__
#ifdef __SSE2__
#ifdef __SSE3__
#ifdef __SSE4_1__
#ifdef __AVX__
...etc...
更新:显然,在使用 Visual Studio 时,上述宏不会自动为您预定义(即使它们在我曾经使用过的所有其他 x86 编译器中),所以您可能需要如果您想要 gcc、clang、ICC、et al...
的可移植性,请自行定义它们【讨论】:
__SSEn__ 宏(但他们确实设置了 __AVX__ 和 __AVX2__)。
__SSEn__ 宏,但微软没有。
_M_IX86_FP扩展为一个值,指示使用了哪个 /arch 编译器选项:
- 如果使用了 /arch:IA32,则为 0。
- 如果使用了 /arch:SSE,则为 1。
- 2 如果使用了 /arch:SSE2。如果未指定 /arch,则此值为默认值。
我没有看到任何提及_SSE_。
【讨论】:
这是一个较晚的答案,但在 MSDN 上你可以找到一篇关于 __cpuid 和 __cpuidex 的文章。我把这个类重新编写成一个函数,它检查 MMX、SSE、SSE2、SSE3、SSSE3、SSE4.1 的支持。 https://docs.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=vs-2019
[[nodiscard]] bool CheckSimdSupport() noexcept
{
std::array<int, 4> cpui;
int nIds_{};
std::bitset<32> f_1_ECX_{};
std::bitset<32> f_1_EDX_{};
std::vector<std::array<int, 4>> data_;
__cpuid(cpui.data(), 0);
nIds_ = cpui[0];
for (int i = 0; i <= 1; ++i)
{
__cpuid(cpui.data(), i);
data_.push_back(cpui);
}
if (nIds_ >= 1)
{
f_1_ECX_ = data_[1][2];
f_1_EDX_ = data_[1][3];
}
// f_1_ECX_[0] - SSE3
// f_1_ECX_[9] - SSSE3
// f_1_ECX_[19] - SSE4.1
// f_1_EDX_[23] - MMX
// f_1_EDX_[25] - SSE
// f_1_EDX_[26] - SSE2
return f_1_ECX_[0] && f_1_ECX_[9] && f_1_ECX_[19] && f_1_EDX_[23] && f_1_EDX_[25] && f_1_EDX_[26];
}
【讨论】:
gcc -O3 -march=native 等效的 AFAIK,它实际上在编译时检测构建主机 CPU。