mal*_*dez 18 c++ windows assembly instruction-set cpuid
有趣的是它在游戏和其他软件中的工作原理。
更准确地说,我正在寻求一个解决方案C++。
就像是:
if AMX available -> Use AMX version of the math library
else if AVX-512 available -> Use AVX-512 version of the math library
else if AVX-256 available -> Use AVX-256 version of the math library
etc.
Run Code Online (Sandbox Code Playgroud)
我的基本想法是在不同的 DLL 中编译库并在运行时交换它们,但这对我来说似乎不是最好的解决方案。
Pet*_*des 12
请参阅xgetbv 和 CPUID 检查是否足以保证 AVX2 支持?其中显示了如何检测 CPU 和操作系统对新扩展的支持:cpuid和xgetbv,分别。
添加需要在上下文切换时保存/恢复的新的/更广泛的寄存器的 ISA 扩展也需要得到操作系统的支持和启用,而不仅仅是 CPU。如果操作系统没有设置控制寄存器位,像 AVX-512 这样的新指令仍然会在支持它们的 CPU 上出错。(有效地承诺它了解它们并将保存/恢复它们。)英特尔设计的东西是故障模式,而不是CPU迁移时寄存器的静默损坏,或使用扩展的两个程序之间的上下文切换。
添加新或更宽寄存器的扩展有 AVX、AVX-512F 和 AMX。操作系统需要了解它们。(AMX 非常新,添加了大量状态:8 个块寄存器T0-T7,每个 1KiB。显然操作系统需要了解 AMX才能使电源管理正常工作。)
操作系统不需要了解 AVX2/FMA3(仍然是 YMM0-15),或者仍然使用 k0-k7 和 ZMM0-31 的任何各种 AVX-512 扩展。
没有独立于操作系统的方法来检测 SSE 的操作系统支持,但幸运的是它已经足够老了,现在您不必这样做。它和 SSE2 是 x86-64 的基准。SSE4.2 之前的所有内容都使用相同的寄存器状态 (XMM0-15),因此操作系统对 SSE1 的支持足以让用户空间使用 SSE4.2。SSE1 于 1999 年随 Pentium 3 一起推出。
不同的编译器有不同的CPUID和检测方式xgetbv。看看gcc 的 __builtin_cpu_supports 检查操作系统支持吗?- 不幸的是,没有,只有 CPUID,至少在被问到时是这样。我认为这是一个 GCC 错误,但我不知道它是否被报告或修复。
通常将函数指针设置为某些重要函数的选定版本。通过函数指针进行内联通常是不可能的,因此请确保正确选择边界,例如包含循环而不仅仅是单个向量的函数的 AVX-512 版本。
GCC 的函数多版本控制可以为您实现自动化,透明地编译多个版本并挂钩一些函数指针设置。
之前已经有一些关于不同编译器的问答,搜索“CPU调度avx”或类似的东西,以及其他搜索词。
请参阅使用 SSE / AVX Intrinisics 时的架构效果,了解 GCC/clang 的内在函数模型之间的差异,在使用内在函数之前,您必须启用-march=skylake或手动启用-mavx2。与 MSVC 和经典 ICC 相比,您可以在任何地方使用任何内部函数,甚至可以发出编译器无法自动向量化的指令。(这些编译器根本不能或根本不优化内在函数,也许是因为这可能会导致它们被从if(cpu)语句中剔除。)
Windows 提供IsProcessorFeaturePresent,但 AVX 支持不在列表中。
如需更详细的检测,您需要直接询问CPU。在 x86 上,这意味着 CPUID 指令。Visual C++__cpuidex为此提供了内部函数。在您的情况下,功能/叶 1 并检查 ECX 中的位 28。维基百科有一篇不错的文章,但您确实应该下载英特尔指令集手册作为参考。