当前位置: 首页 > 知识库问答 >
问题:

应用程序如何确定指令集是否可用,并在可用时使用它?

齐甫
2023-03-14

它在游戏和其他软件中的工作方式很有趣。
更准确地说,我在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中编译库,并在运行时交换它们,但这似乎不是我的最佳解决方案。

共有2个答案

闻深
2023-03-14

查看xgetbv和CPUID检查是否足以保证AVX2支持?它展示了如何检测CPU和OS对新扩展的支持,分别是< code>cpuid和< code>xgetbv。

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

增加新的或更宽的寄存器的扩展是AVX、AVX-512F和AMX。操作系统需要了解它们。(AMX非常新,增加了大量的状态:8个tile寄存器T0-T7,每个1kb。显然,操作系统需要了解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错误,但IDK,如果它被报告或修复的话。

通常设置指向某些重要功能的选定版本的函数指针。通常不可能通过函数指针进行内联,因此请确保正确选择边界,例如包含循环(而不仅仅是单个向量)的函数的 AVX-512 版本。

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

以前有过一些问题

查看使用SSE / AVX内联函数时的架构效果,了解GCC/clang内联函数模型之间的差异,在GCC/clang内联函数模型中,在使用内联函数之前,必须启用< code>-march=skylake或其他功能,或者手动启用< code>-mavx2。与MSVC和经典ICC相比,你可以在任何地方使用任何内部函数,甚至可以发出编译器无法自动矢量化的指令。(这些编译器不能或根本不优化内部函数,可能是因为这可能会导致它们被< code>if(cpu)语句吊出来。)

邵博远
2023-03-14

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

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

 类似资料:
  • 在C/C中,可以对SIMD(如AVX和AVX2)指令使用内部函数。有没有办法在Rust中使用SIMD?

  • 问题内容: 好的,因此我们正在尝试将3D散点图合并到NetBeans 7.0中的项目中,而我们选择测试的库之一就是Jzy3D。看起来它可以完成我们需要做的所有事情,但是不幸的是,它什么也没做。 我已经正确安装了JOGL,并对其进行了测试并发现它可以正常工作。然后,我包含了与演示中相同的依赖项。我也尝试过直接包括.jars。是的,胶原- rt.jar在库文件夹中。 编辑: 为了使JOGL工作,我们不

  • 不是一个真正重要的问题,但只是好奇。您可以在运行时更改应用程序图标吗?例如,有一个按钮,当您按下该按钮时,您会在flutter中获得不同的应用程序图标(假设应用程序图标已经“设置”)。Android和iOS。 非常感谢任何意见。谢谢

  • 我有以下PAC文件代码: 根据Java这应如下(https://docs.oracle.com/cd/E19575-01/821-0053/adyrr/index.html): 在以下示例中,返回值告诉浏览器使用端口8080上名为w3proxy.example.com的代理。如果该代理不可用,浏览器将使用端口8080上名为proxy1.example.com的代理: 代理w3proxy。实例com

  • 我们正在Android上构建聊天应用程序。我们正在考虑使用HTTP REST API发送出站消息。想知道与使用WebSockets或XMPP(这似乎更像是传输聊天消息的实际标准)相比,这是一种好方法还是有缺点? 我能想到的一些利弊是: < li>HTTPendpoint很容易在服务器端水平扩展(这是主要问题) < li >与HTTP相比,Websockets的学习曲线更加陡峭 与WebSocket

  • 我有int的向量,我需要找到并用特定的值替换一些元素。他们都是一样的 例如:将所有元素的4替换为8。 我正在尝试c中循环中的直接内存访问。但对我来说还是很慢。 更新: 我正在上使用OpenCV对象: 函数仅在释放模式下通过指针返回值