【问题标题】:Using xmm parameter in AVX intrinsics在 AVX 内部函数中使用 xmm 参数
【发布时间】:2026-01-23 10:35:02
【问题描述】:

是否可以将 xmm 寄存器参数与 AVX 内在函数 (_mm256_**_**) 一起使用?

我的代码需要使用向量整数运算(用于加载和存储数据)以及向量浮点运算。整数代码使用 SSE2 内部函数编写以兼容旧 CPU,而浮点代码使用 AVX 编写以提高速度(还有 SSE 代码分支,所以不建议这样做)。

目前,除了使用编译器标志将所有SSE指令自动转换为VEX编码版本外,有没有办法使用内在函数(即没有内联/外部汇编)来强制在XMM寄存器上使用VEX编码指令?

注意:我试过_mm256_castsi128_si256(),这会生成带有 ymm 操作数的指令。

【问题讨论】:

标签: intrinsics avx


【解决方案1】:

您有一个带有 AVX 的处理器。它没有 XMM 寄存器,只有 YMM 寄存器。如果您使用 AVX 支持编译所有代码(例如,在 GCC 中使用 -mavx 或在 MSVC 中使用 /arch:AVX),那么所有 SSE2 代码都在 YMM 寄存器的低 128 位上运行。没什么好担心的。

但是,假设您有两个不同的模块,一个是使用 SSE2 支持编译的(例如,在 GCC 中使用 -msse2 或在 MSVC 中使用 /arch:SSE2),另一个具有 AVX 支持,并且您使用两者的函数,那么您确实有一些东西担心何时在它们之间切换。在这种情况下,当您从 AVX 切换到 SSE2 代码时,您应该调用 _mm256_zeroupper() or _mm256_zeroall(),除非您想降低性能。 Using AVX CPU instructions: Poor performance without "/arch:AVX"

简单的解决方案是使用 AVX 支持编译所有代码。我能想到编译具有不同指令集支持的不同模块的唯一原因是,如果您想制作一个 CPU 调度程序,以便您的代码可以在不同的处理器上运行。实施起来有点痛苦。但是你不做状态改变所以我唯一能想到你需要担心状态改变的时候是当你从一个共享库中调用函数时,这些函数是用另一个指令集编译的(例如一个用 SSE2 编译的 DLL)。在这种情况下,您可能需要在从 AVX 代码调用库函数时调用 _mm256_zeroupper() or _mm256_zeroall()

【讨论】:

  • 我已经为 SSE2 和 SSE3 代码路径设置了调度程序。 ICC 可以为每个函数生成 SSE2 指令的 VEX 前缀版本,但我无法让 MSVC 使用它。而且由于这个项目本身已经是 dll(它是一个 Avisynth 插件),我不想加载另一个小 DLL。我想知道是否有明确的指令编译器可以创建 VEX 编码的 SSE2 指令。
  • 您正在尝试制作调度程序并且在使用 MSVC 时遇到问题?然后,您应该将信息添加到您的问题中。不久前我自己尝试过这样做cpu-dispatcher-for-visual-studio-for-avx-and-sse
  • 这不是我的主要观点,尽管它是结果。我想知道是否可以使用内部函数执行 VEX 编码的 SSE2 指令。
  • 这可能超出了我的认知。我会天真地假设,如果您使用支持 AVX 的 SSE2 内部函数(例如,使用 /arch:AVX)编译代码,那么它是 VEX 编码的。