如何以编程方式检查 CPU 上是不是启用了 fused mul add (FMA) 指令?
Posted
技术标签:
【中文标题】如何以编程方式检查 CPU 上是不是启用了 fused mul add (FMA) 指令?【英文标题】:How to programmatically check if fused mul add (FMA) instruction are enabled on the CPU?如何以编程方式检查 CPU 上是否启用了 fused mul add (FMA) 指令? 【发布时间】:2019-11-19 10:47:24 【问题描述】:我想使用 FMA 内部指令 _mm256_fmadd_pd(a, b, c),但我的代码必须在启用或不启用 FMA 的不同计算机上运行。我不能使用编译时标志。所以我希望能够写出这样的东西:
__m256d a, b, c, x;
bool FMA_Enabled = CheckFMA();
if (FMA_Enabled)
d = _mm256_fmadd_pd(a, b, c);
else
x = _mm256_mul_pd(a, b);
d = _mm256_add_pd(x, c);
我找不到编写函数 CheckFMA() 的方法。有没有办法做到这一点?
我的操作系统是 Windows 10 64 位。
编辑:分支实际上将在函数之外。所以我不会因为每次都检查 FMA 支持而损失性能。
【问题讨论】:
你是说增加的乘法性能优于分支(否则没有必要)?你测量过这个吗? @lisyarus 不,这没有错。每个 CPU 都有用于特征检测的 API,因此不必输入无效指令。 见***.com/q/6121792/2747962 查看__cpuid
Microsoft intrinic 并检查AVX2
和FMA
函数。
@DanielsaysreinstateMonica:_mm256_fmadd_pd
只需要 AVX 和 FMA3 功能位,而不需要 AVX2。您不想不必要地排除 AMD Piledriver/Steamroller。从技术上讲,您需要检查操作系统是否支持 AVX(以及 CPU),但 Windows 程序可能能够假定非古代 Windows。真的只需要检查 FMA3 功能位;它暗示了 AVX,因为这就是它的编码方式。 (与 AMD 放弃的 FMA4 功能相反)
【参考方案1】:
我使用 __cpuid 通过修改 microsoft 代码来编写我的函数。非常感谢大家的帮助。
#include <intrin.h>
#include <vector>
#include <bitset>
#include <array>
bool CheckFMA()
std::array<int, 4> cpui;
std::bitset<32> ECX;
int nIds;
bool fma;
__cpuid(cpui.data(), 0);
nIds = cpui[0];
if (nIds < 1)
return false;
__cpuidex(cpui.data(), 1, 0);
ECX = cpui[2];
return ECX[12];
【讨论】:
您不需要在循环中调用cpuid
来枚举所有可能的输出。您只需要在if(nIds_ >= 1)
中使用__cpuidex(cpui.data(), 1, 0)
即可获得您读过的一页。这对性能来说并不是一个巨大的灾难,例如Ice Lake only has 0x1B
"basic" / 低编号 CPUID 留待枚举。所以它不会让启动需要额外的毫秒。
@PeterCordes。是的,谢谢。我将在我的帖子中更正这一点。
不要把笨重的版本留在答案中,只显示好的版本。或者至少把它放在第一位。编辑以创建您应该首先发布的答案;如果有人想看,编辑历史就在那里。
顺便说一句,理论上(如果您的代码可能在古老的操作系统下运行),您需要检查操作系统对 AVX 的支持是否已启用。 Which versions of Windows support/require which CPU multimedia extensions?。操作系统必须在 CPU 中设置一个位以使它们不会出错。 (这避免了在不知道新架构状态的操作系统上的上下文切换上损坏的 AVX 上半部分的故障模式。)【参考方案2】:
哪个操作系统?运行 linux,您可以检查 /proc/cpuinfo
,例如fma 标志
使用 Windows 看看https://docs.microsoft.com/en-us/sysinternals/downloads/coreinfo 使用了GetLogicalProcessorInformation
函数
【讨论】:
我忘了指定操作系统:它是 windows 10 64 位。 直接使用cpuid
不会比其中任何一个更容易(而且更快)吗?
我认为 cpuid 是正确的方法。非常感谢以上是关于如何以编程方式检查 CPU 上是不是启用了 fused mul add (FMA) 指令?的主要内容,如果未能解决你的问题,请参考以下文章
如何在android studio上以编程方式检查自动启动权限是启用还是禁用
如何以编程方式检查系统上是不是安装了 SQL Server Management Studio?
如何以编程方式在WooCommerce产品中启用评论和评分?