不能在旧的 Intel CPU 上将 _m_prefetchw intrinsic 与 gcc/clang -march=native 一起使用?

Can't use _m_prefetchw intrinsic with gcc/clang -march=native on older Intel CPU?

我 运行 在使用 Clang 编译我的项目时遇到了这个问题。我想使用内在函数 _m_prefetchw 作为我包含的 x86intrin.h,但由于某种原因我的流程没有达到 _m_prefetchw 定义。 我检查了 Clang 的 x86intrin.h 头文件,但我没有定义 __PRFCHW__ 以包含 prfchwintrin.h 尽管我的 PC 确实支持 PREFETCHW(我 运行 coreinfo 知道这一点)。

有谁知道为什么 __PRFCHW__ 没有定义,尽管我支持 PREFETCHW

代码示例:

#include <x86intrin.h>

int main(){
    int i = 10;
    _m_prefetchw(&i);
    return 0;
}

在 运行 之后我得到错误 error LNK2019: unresolved external symbol _m_prefetchw referenced in function main

我深入研究了我的 clang 包含头文件并在 x86intrin.h:

中找到了这个
#if !defined(_MSC_VER) || __has_feature(modules) || defined(__PRFCHW__)
#include <prfchwintrin.h>
#endif

_m_prefetchw是在prfchwintrin.h文件中定义的。

我的处理器是 Intel Xeon E5-2690,Clang 版本是 9.0.1。

手动使用 -mprfchw 告诉编译器让您使用 _m_prefetchw 即使在为 -march= 编译时也是如此,其中 prefetchw 只是一个 NOP .

-march=native 仅包含 -mprfchw 如果它确实会产生效果。有关编译器如何“考虑”预取指令和 CPUID 的可用性的更多详细信息,请参阅 What is the effect of second argument in _builtin_prefetch()?


您的 E5-2690 是 Sandybridge,比 Broadwell 更早,它引入了(在英特尔方面)对 PREFETCHW 的真正支持。

任何非古代 Intel CPUs 都可以 运行 prefetchw 作为 NOP (http://ref.x86asm.net/coder64.html#gen_note_NOP_0F0D),但只有 Broadwell 和后来才真正宣传 CPU 的 CPUID 中的功能,并且只有 Broadwell 和后来的人真正做与 NOP 不同的事情。 (自从 3DNow! 引入它以来,AMD CPU 就支持它作为进入独占状态的实际预取。)

运行 作为 NOP 而不是错误显然是安装 64 位 Windows 所必需的,因此很多关于“支持”PREFETCHW 的讨论都围绕着不错误,而不是它的 CPUID 位和实际做任何事情。例如,Windows 10 64-bit requirements: Does my CPU support PrefetchW? 上的评论讨论了“支持”(如不会出错)与“支持”如实际做某事的区别。

forum thread 提到 P4 Nocona 在 prefetchw 上出现故障,因此无法安装 Windows 8.1。但是 Core2 和更高版本确实有“不会出错”的支持。