使用较新版本的 g++ 导致多线程性能下降?



我写了一些C++反向传播代码,我在 Ubuntu 18.04 的 i9-9900K 上运行。

我看到的问题是,使用较新版本的 g++ 时,我的多线程性能越来越差。

单线程基准测试在较新的 g++ 版本中按预期改进:

g++ 4.8: 5437 cycles/s
g++ 5.5: 5929 cycles/s
g++ 6.5: 5932 cycles/s
g++ 7.4: 6117 cycles/s
g++ 8.3: 6921 cycles/s

多线程基准测试(8 个内核上的 14 个 pthread)在较新版本中会显著降级:

g++ 4.8: 25456 cycles/s
g++ 5.5: 17212 cycles/s
g++ 6.5: 18616 cycles/s
g++ 7.4: 17054 cycles/s
g++ 8.3: 14797 cycles/s

我在 CentOS 7.6 和 Clear Linux 中也看到了类似的行为。 在所有测试的操作系统中,最快的性能来自使用 g++ 4.8 的 14 个线程。

以下是我正在使用的编译标志: g++ -c -std=c++11 -march=native -Ofast

我是否使用了错误的标志进行编译? 我试过-O3,退化相似,虽然不那么极端(并且比-Ofast慢)

g++ 4.8 -O3: 17256 cycles/s
g++ 5.5 -O3: 15129 cycles/s
g++ 6.5 -O3: 15779 cycles/s
g++ 7.4 -O3: 15736 cycles/s
g++ 8.3 -O3: 13361 cycles/s

我觉得我在这么多内核时遇到了内存带宽问题。 是否有任何编译选项可以帮助减轻这么多线程的内存压力?

进一步的测试表明,该问题与 -march=native 优化标志有关。

G++ 4.8 将 i9-9900K 原生视为 core-avx2,可激活: MMX、SSE、SSE2、SSE3、SSSE3、SSE4.1、SSE4.2、AVX、AES 和 PCLMUL

G++ 4.9 及更高版本将 i9-9900K 视为 Broadwell,可激活: MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX 和 PREFETCHW

显然,这以某种方式导致了过度优化。

完全删除 -march 标志解决了这个问题。禁用 AVX 也可以使用 -mno-avx 和 -mno-avx2

最新更新