【问题标题】:SSE gives no speedup for C++ number crunchingSSE 没有为 C++ 数字运算提供加速
【发布时间】:2015-07-29 14:10:06
【问题描述】:

我有一个执行图像处理的繁重的数字运算程序。它主要是卷积。它是用 C++ 编写的,并使用 Mingw GCC 4.8.1 编译。我在配备 Intel Core i7 4900MQ(SSE 最高 SSE4.2 和 AVX2)的笔记本电脑上运行它。

当我告诉 GCC 使用 SSE 优化(使用 -march=native -mfpmath=sse -msse2 )时,与使用默认的 x87 FPU 相比,我发现没有加速。

当我使用双精度而不是浮点数时,没有减速。

我的理解是,当使用浮点数而不是双精度数时,SSE 应该给我 2 倍的加速。我弄错了吗?

【问题讨论】:

  • 您是否检查了生成的程序集以查看代码是否真的被矢量化了?您是否尝试过 GCC 的调试选项 (-ftree-vectorizer-verbose) 来查看代码是否真的被矢量化了?
  • 在这种情况下,浮点运算可能不会限制您的性能。从您的问题来看,您似乎是在没有其他优化的情况下进行编译?
  • 你确定 gcc 以前甚至使用过 x87 FP 吗?至少对于 x86-64,默认值一直是 fpmath=sse,这对于标量代码来说应该只会比 x87 提供一点加速。如果编译器可以向量化任何东西,并且它不受内存限制,那么您可以期待 -march=native 的加速
  • 如果你不是为 x86-64 编译,你真的应该。 x86 调用约定在堆栈中包含 args,而不是在寄存器中,因此使用 FP args 和 FP 返回值调用非内联函数意味着将 args 从堆栈加载到 xmm 寄存器,然后将结果存储到临时缓冲区,然后加载结果进入 x87 FPU,ABI 说返回值必须去。 (-mfpmath=sse 不会更改 ABI,只会更改函数内部发生的情况。不过,如果您的热循环具有内联的任何函数调用,这才是最重要的)。
  • Mingw GCC 是 32 位的,因此它针对的是 x86 系统,默认情况下 SSE 是禁用的。我会研究 Mingw-64 看看我是否能从中得到改进。

标签: c++ gcc sse x87


【解决方案1】:

我的理解是,当使用浮点数而不是双精度数时,SSE 应该给我 2 倍的加速。我弄错了吗?

是的,你是。

编译器与您的代码一样好 - 请记住这一点。如果您在设计算法时没有考虑到矢量化,那么编译器将无能为力。这并不容易:“打开开关,享受 100% 的性能提升”。

首先,用-ftree-vectorizer-verbose=N 编译你的代码,看看编译器真正向量化了什么。

N 是详细级别,将其设为5 以查看所有可用输出(更多信息can be found here)。

另外,您可能想阅读about GCC's vectorizer

请记住,对于性能关键的代码部分,直接使用 SSE/AVX 内部函数 (brilliantly documented here) 可能是最佳选择。

【讨论】:

  • 我使用了 -ftree-vectorizer-verbose=N,它显示除非我使用 -O3,否则没有任何东西被矢量化,即使那样,大多数代码也无法矢量化,因为它包含控制语句。所以我确实错了,你的回答帮助我理解了原因。谢谢。
【解决方案2】:

没有代码,没有关于测试过程的说明,但一般可以这样解释:

  1. 这不仅仅与 CPU 限制有关,它还受到内存速度的限制。 图像处理通常有很大的工作集并且超过非至强 CPU 的缓存量。最终,cpu 遇到饥饿意味着整体吞吐量会受到内存速度的限制。

  2. 您可能正在使用对矢量化不友好的算法。 并非每个算法都能从矢量化中受益。需要满足很多条件——流依赖、内存布局等。

【讨论】:

  • 他说从float 更改为double 时没有减速,因此排除了内存瓶颈(除非局部性很糟糕,并且大多数负载没有被预取,所以内存延迟是问题,而不是带宽。)但问题可能是#2:自动矢量化失败。标量 SSE 数学几乎不比标量 x87 数学快。长依赖链很容易成为瓶颈,留下足够的执行资源来处理使用 x87 而不是平面 xmm 寄存器时所需的额外存储/加载/x87 堆栈操作。
  • 所以原因是 #2,但 Peter Cordes 也是正确的,内存带宽(和缓存大小)不是这里的瓶颈(如果他们使用双精度数会减慢程序的速度)。因此性能可能会受到内存延迟(因为缓存填充不佳)或 CPU 非矢量化性能的限制。
猜你喜欢
  • 1970-01-01
  • 2019-03-29
  • 2018-03-27
  • 1970-01-01
  • 2020-01-07
  • 2019-01-11
  • 1970-01-01
  • 2014-12-21
  • 2018-01-21
相关资源
最近更新 更多