【问题标题】:Why does MSVC use SSE2 instruction for such trivial thing?为什么 MSVC 使用 SSE2 指令来处理这种琐碎的事情?
【发布时间】:2015-01-23 10:50:47
【问题描述】:

代码:

double Ret_Value=0;

在默认设置下 VS2012 编译为:

10112128  xorps       xmm0,xmm0  
1011212E  movsd       mmword ptr [Ret_Value],xmm0

如果在项目设置中禁用 SSE2,则编译为:

101102AC  fldz  
101102AE  lea         eax,[Ret_Value]  
101102B1  push        eax  
101102B2  fstp        qword ptr [Ret_Value] 

编辑:我不确定pushlea 是否与此初始化有关,也许是为了在那之后完成的工作,只是反汇编显示了这行C++ 代码。

SSE2 明显更好吗?除了它是 2 指令短?这里做了什么样的优化?

这是如何发现的:应用在不支持 SSE2 的旧处理器上开始出现故障。

【问题讨论】:

  • 我认为这是一个简单的代码大小优化。较短的代码对缓存更友好,因此速度更快。此外,不使用堆栈可以节省一些内存访问。
  • 不确定中间的 2 条指令应该做什么。只需要将Ret_Value 归零,您只需要fldz; fstp [Ret_Value]
  • 检查this post,它解释了为什么 FPU 是邪恶的,英特尔决定更换它。编译器作者花了一段时间才效仿,微软是最后一个主流。
  • 带有 /arch:IA32 的 MSVC 不会为 32 位代码生成任何 SSE 指令。 MSVC x64 本机代码生成使用 SSE/SSE2 并且没有 x87 指令。使用 /arch:SSE 或 /arch:SSE2 的 MSVC 32 位尝试使用 SSE 指令和其他 x64 本机代码生成机制。从 VS 2012 开始,32 位编译器默认为 /arch:SSE2——Windows 8.0 明确要求 x86(32 位)支持 SSE/SSE2,并且所有 Windows x64 处理器都需要它。
  • SSE2 是 x86-64 的基线,无论 Windows 是什么,以防有人想知道。 (当然,在 64 位代码中,您也可以 push qword 0mov qword ptr [rsp+8], 0 在一条指令中存储 8 个字节的零。)

标签: optimization visual-c++ x86 sse fpu


【解决方案1】:

英特尔优化参考手册第 3.8.1 节(优化浮点代码的指南)说 -

通过适当的开关使编译器能够使用 SSE、SSE2 和更高级的 SIMD 指令集(例如 AVX)。 支持标量 SIMD 代码生成以替代 x87 代码生成。

第 3.8.5 节继续解释:

除非您需要 x87 功能,否则请使用 Streaming SIMD Extensions 2 或 Streaming SIMD Extensions。大多数 SSE2 算术运算的延迟都比 X87 对应的要短,并且它们消除了与 X87 寄存器栈的管理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2013-10-27
    • 2019-06-18
    • 2012-09-19
    • 1970-01-01
    相关资源
    最近更新 更多