c++ 如何为MSVC Visual Studio指定目标CPU/架构Haswell?

h5qlskok  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(221)

我有一个程序,大量使用内部命令_BitScanForward/_BitScanForward64(又名计数尾随零,TZCNT,CTZ)。我想 * 不 * 使用内部,而是使用相应的CPU指令(在Haswell和更高版本中提供)。
当使用gcc或clang(其中的内部函数称为__builtin_ctz)时,我可以通过指定-march=haswell-mbmi2作为编译器标志来实现这一点。
_BitScanForward的文档只规定了intrinsic在所有架构"x86,ARM,x64,ARM64"或"x64,ARM64"上可用,但我不只是希望它可用,我希望确保它被编译为使用CPU指令而不是intrinsic函数。
我也搜索了网络,但奇怪的是,几乎没有匹配我的问题,大多数只是解释如何使用intrinsic,例如this questionthis question
我是不是想太多了,如果CPU支持的话,MSVC将创建神奇的使用CPU指令的代码?是否需要任何标志?如何确保CPU指令在可用时被使用?

    • 更新**

这是godbolt的样子。请友好一点,我的汇编阅读技能相当基本。
GCC使用tzcnt搭配haswell/bmi2,否则会使用rep bsf。MSVC使用bsf,但不使用rep
我还发现了这个有用的答案,它指出:

  • "为BSR使用冗余的rep前缀一般被定义为被忽略[...]".我想知道bsf是否也是如此?
  • 它解释了(正如我所知)bsftzcnt不同,但是MSVC似乎不检查input == 0

这增加了以下问题:为什么bsf适用于MSVC?

    • 更新**

好的,这很简单,我实际上调用_BitScanForward来表示MSVC。

    • 更新**

所以我在这里添加了一些不必要的混淆。理想情况下,我希望使用一个固有的__tzcnt,但MSVC中不存在,所以我求助于_BitScanForward加上一个额外的检查来说明0输入。
但是,MSVC支持LZCNT,我在这里遇到了类似的问题(但是在我的代码中很少使用它)。
略微更新的问题为:MSVC如何处理LZCNT(而不是TZCNT)?

    • 答案:**请参见here。具体如下:在不支持lzcnt指令的Intel处理器上,指令字节编码作为bsr(位扫描反向)执行。如果代码可移植性是一个问题,请考虑使用_BitScanReverse内在函数。

这篇文章建议如果老的CPU是一个问题,就求助于bsr。对我来说,这意味着没有编译器标志来控制这一点,相反,他们建议手动识别__cpu,然后调用bsrlzcnt
简而言之,MSVC不支持不同的CPU架构(x86/64/ARM以外)。

p4tfgftt

p4tfgftt1#

正如我在上面发布的,MSVC似乎不支持不同的CPU体系结构(x86/64/ARM之外)。
This article says:"在不支持lzcnt指令的英特尔处理器上,指令字节编码作为bsr(位扫描反向)执行。如果考虑代码可移植性,请考虑使用_BitScanReverse内部函数。"
文章建议如果老CPU是一个问题,就求助于bsr。对我来说,这意味着没有编译器标志来控制这一点,相反,他们建议手动识别__cpuid,然后根据结果调用bsrlzcnt

    • 更新**

正如@defaffled所指出的,x64 intrinsics list中确实存在_tzcnt_u32/_tzcnt_u64
我在查看窗格左侧的Alphabetical listing of intrinsic functions时被误导了。我想知道"intrinsic"和"intrinsic函数"之间是否有区别,即_tzcnt_u64是intrinsic但不是intrinsic函数。

相关问题