应用程序如何确定指令集是否可用,并在可用的情况下使用它



它在游戏和其他软件中的工作方式很有趣
更确切地说,我要求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.  

我的基本想法是在不同的DLL中编译库,并在运行时交换它们,但这似乎不是我的最佳解决方案

用于检测部分

请参阅xgetbv和CPUID检查是否足以保证AVX2支持显示了如何检测CPU和操作系统对新扩展的支持:分别为cpuidxgetbv

添加需要在上下文切换上保存/恢复的新/更宽寄存器的ISA扩展也需要由操作系统支持和启用,而不仅仅是CPU。如果操作系统没有设置控制寄存器位,像AVX-512这样的新指令在支持它们的CPU上仍然会出现故障。(有效地保证它知道它们,并将保存/恢复它们。(英特尔设计的东西是故障模式,而不是CPU迁移时寄存器的无声损坏,或者使用扩展在两个程序之间切换上下文。

添加新的或更宽寄存器的扩展是AVX、AVX-512F和AMX。OS需要了解它们。(AMX是非常新的,并添加了大量的状态:每个1KiB的8个瓦片寄存器T0-T7。显然,操作系统需要了解AMX才能正常工作。(

OS不需要知道AVX2/FMA3(仍然是YMM0-15(,或者仍然使用k0-k7和ZMM0-31的各种AVX-512扩展中的任何一个。

没有独立于操作系统的方法来检测SSE的操作系统支持,但幸运的是,它已经足够旧了,现在你不必这么做了。它和SSE2是x86-64的基线。SSE4.2之前的所有东西都使用相同的寄存器状态(XMM0-15(,因此操作系统对SSE1的支持足以让用户空间使用SSE4.2。SSE1是1999年新推出的奔腾3。

不同的编译器有不同的方法来检测CPUID和xgetbv。请参阅do gcc';s __builtin_cpu_supports是否检查操作系统支持?-不幸的是,没有,只有CPUID,至少在被问到的时候是这样。我认为这是一个GCC错误,但IDK,如果它被报告或修复的话。


对于可选使用部件

通常将函数指针设置为某些重要函数的选定版本。插入函数指针通常是不可能的,所以请确保适当地选择边界,比如AVX-512版本的函数,它包括一个循环,而不仅仅是一个向量。

GCC的函数多版本控制可以为您实现自动化,透明地编译多个版本并挂接一些函数指针设置。

之前有一些问答;对于不同的编译器来说;CPU调度avx";或者类似的东西,以及其他搜索词。

请参阅使用SSE/AVX内部时的体系结构影响,以了解GCC/clang的内部模型之间的差异,在使用内部之前,必须启用-march=skylake或其他什么,或者手动启用-mavx2。与MSVC和经典的ICC相比,在它们中,您可以在任何地方使用任何内部,甚至可以发出编译器无法自动向量化的指令。(这些编译器不能或根本没有对内部函数进行太多优化,也许是因为这可能会导致它们被从if(cpu)语句中删除。(

Windows提供IsProcessorFeaturePresent,但AVX支持不在列表中。

对于更详细的检测,您需要直接询问CPU。在x86上,这意味着CPUID指令。Visual C++为此提供了__cpuidex内部函数。在您的情况下,函数/叶1和ECX中的检查位28。维基百科上有一篇不错的文章,但你真的应该下载英特尔指令集手册作为参考。

相关内容

  • 没有找到相关文章

最新更新