【发布时间】:2018-09-25 14:00:01
【问题描述】:
我在一些网站上读到,当使用 SSE2 架构并检测 AVX 支持运行时时,MSVC 实际上可以发出 AVX 指令。是真的吗?
我测试了各种肯定会受益于 AVX/AVX2 支持的循环,但在调试器中运行时,我真的找不到任何 AVX 指令。
当使用 /arch:AVX 时,它会发出 AVX 指令,但它当然会在不支持它的 CPU 上崩溃(经过测试),因此也没有运行时检测。我可以使用 AVX 内在函数,它会成功地从它们创建 AVX 指令。有什么想法吗?
【问题讨论】:
-
上次我检查过,在 MSVC 中使用没有
/arch:AVX的 AVX 内部函数用于该编译单元是一个坏的想法。您可以获得导致 SSE/AVX 转换惩罚的代码,因为它将对任何指令使用非 VEX 编码,即使在具有 VEX 指令的函数中也是如此。 Why is this SSE code 6 times slower without VZEROUPPER on Skylake? -
我正在使用 VZEROUPPER。无论如何,这不是问题 - 我最感兴趣的是 MSVC 是否可以通过运行时检查将 C++ 循环实际编译为 /arch:sse2 中的 AVX(和更高指令集)代码。
-
对,但我猜你只是在函数末尾使用
vzeroupper。我的意思是没有/arch:AVX的MSVC 可以在一个函数中混合SSE 和VEX。例如考虑用_mm256_extractf128_ps进行水平求和到__m128,所以你使用一些128 位内在函数,比如_mm_add_ps。那些将使用非 VEX 编码,并且将那些与 VEX 编码的 shuffle(如vpermilps或更多_mm256_add_ps)混合在一起,将对 Haswell 的性能造成灾难性影响。 -
一开始也是......无论如何,通常我实际上是用 /arch:AVX 编译它并手动检测 AVX 支持。但同样,这不是这里的问题......“我最感兴趣的是 MSVC 是否可以通过运行时检查将 C++ 循环实际编译成 /arch:sse2 中的 AVX(和更高指令集)代码。”我还假设它足够聪明,可以在需要时将高 ymm regs 归零。
标签: visual-c++ compiler-optimization cpu-architecture avx auto-vectorization