程序(提供的源代码)在 Ivy Bridge Xeon 上花费 运行 的时间是旧移动 Sandy Bridge 的两倍
Program (source provided) takes twice as long to run on Ivy Bridge Xeon than older mobile Sandy Bridge
我有两台计算机正在尝试 运行 同一个程序。尽管该程序在系统 B 上应该 运行 至少快一点,但实际上它在系统 A 上快两倍(或更好)。这对我来说毫无意义,如果有人能帮我计算,我真的很乐意找出世界上是什么导致了这个奇怪的性能问题。我添加了第三个系统作为健全性检查,现在我更加困惑了。
系统A:
- 2011 MacBook Pro with Sandy Bridge CPU
- 英特尔(R) 酷睿(TM) i7-2820QM CPU @ 2.30GHz
- Intel power meter 报告它 运行在 3.1GHz 时 运行在程序中
- 编译器为 clang++:Apple LLVM 版本 6.0 (clang-600.0.57)(基于 LLVM 3.5svn)
系统B:
- 2 插槽,12 cores/socket 2013 年购买的 Ivy Bridge Xeon 服务器
- 英特尔(R) 至强(R) CPU E5-2697 v2 @ 2.70GHz
- turbostat 报告一个核心 运行ning 在 3.5GHz 时 运行ning 程序
- 编译器是 clang++:Ubuntuclang 版本 3.5-1ubuntu1 (t运行k)(基于 LLVM 3.5)
系统 C:
- 四核 Haswell Core i5
- 英特尔(R) 酷睿(TM) i5-4430 CPU @ 3.00GHz
- turbostat 报告内核最大频率为 3.2GHz
- 编译器为 clang++:clang 版本 3.5.1 (tags/RELEASE_351/final)
您可以在以下位置找到该程序的源代码:http://www.cs.binghamton.edu/~millerti/test.tgz
我在两个系统上使用的编译器命令行如下:
- 标量版本:
clang++ -O3 -msse3 x.c 3_22_1b.c
- 矢量版本:
clang++ -O3 -msse3 x.c 3_22_1.c
这有两件相当奇怪的事情。一是标量版本比矢量版本稍快。但真正巨大的问题是这个程序在服务器(系统B)上运行所花的时间是笔记本(系统A)上的两倍多。
在系统 A 上:
$ time ./a.out
real 0m22.908s
user 0m22.853s
sys 0m0.038s
在系统 B 上:
$ time ./a.out
real 0m55.354s
user 0m55.310s
sys 0m0.000s
在系统 C 上:
$ time ./a.out
real 0m42.421s
user 0m42.400s
sys 0m0.000s
其他事实:
- Sandy Bridge 和 Ivy Bridge 具有相同数量的 L1 缓存(总共 64KB)。其实哈斯韦尔也是。
- 系统 B 的二级缓存比其他任何一个都多
- 可执行文件非常小,应该至少大部分适合 L1I 缓存
- 数据量为176个float,所以L1D缓存命中率应该在100%左右
- IVB 和 SB 微架构非常相似,不同之处主要有利于 IVB
- 正在卸载所有系统 运行。笔记本(系统 A)确实有最少的其他事情在进行。服务器(系统 B)和 Haswell(系统 C)完全卸载。没有其他用户或任何东西。
top
显示程序在所有系统中获得 100% CPU。 iotop
显示在此期间服务器上没有 I/O 进行。
- 在任何情况下,与 clang 相比,使用 g++ 都没有太大区别。
- 作为参考,我添加了 Haswell,它没有照亮任何东西。这比 Ivy Bridge 快很多但比 Sandy Bridge 慢是没有意义的。
- 操作系统不可能对这里产生任何影响,而且 Apple 不可能在他们尚未共享的 LLVM 编译器中施展某种魔法,使程序运行得更快。
- 我确实尝试过对 tanh 进行基准测试。事实证明,它在 MacOS X 上的速度大约是 Linux 的两倍。 1 亿次 tanh 调用在系统 A (Mac) 上需要 1.484 秒,而在系统 C (Haswell) 上需要 3.380 秒,在系统 B(IVB 服务器)上需要 3.392 秒。不过,我做过profiling,tanh只占总时间的35%左右运行,所以不能解释整个性能差距
-ffast-math
没有帮助。
- 我正在 Mac 上的虚拟机中安装 Linux。我将 运行 Linux 和 Mac 上的相同代码,以查看 glibc 的慢数学有多少以及 CPU 有多少。 (由于这是计算密集型,虚拟化无关紧要。)我稍后会添加结果。
您需要检查汇编列表。一个编译器可能会生成 SISD 指令,而另一个 SIMD - 例如 mulss xmm0, xmm7 而不是 mulps xmm0, xmm7,它可以快四倍(在相同的 CPU GHz 下)。然后有AVX指令可以试试。
您描述的问题通常是由较旧的编译器生成的速度最慢引起的,或者就我而言,使用最新的免费 Microsoft 编译器与 Linux 的最新 GCC 相比,后者生成了卓越的实现。
原因完全是tanh
。由于分析开销,分析没有揭示这一点。我不知道为什么我昨晚没有想到这个,但是今天早上,我注释掉了 tanh,这就是我得到的:
系统A:
$ time ./a.out
real 0m4.443s
user 0m4.433s
sys 0m0.008s
系统 B:
$ time ./a.out
real 0m3.373s
user 0m3.368s
sys 0m0.003s
系统 C:
$ time ./a.out
real 0m4.054s
user 0m4.050s
sys 0m0.000s
这些数字都有道理。所以结论是 tanh 的 Linux 实现真的很糟糕。我必须自己实现或从 BSD libc 获取 tanh 源代码。
我有两台计算机正在尝试 运行 同一个程序。尽管该程序在系统 B 上应该 运行 至少快一点,但实际上它在系统 A 上快两倍(或更好)。这对我来说毫无意义,如果有人能帮我计算,我真的很乐意找出世界上是什么导致了这个奇怪的性能问题。我添加了第三个系统作为健全性检查,现在我更加困惑了。
系统A:
- 2011 MacBook Pro with Sandy Bridge CPU
- 英特尔(R) 酷睿(TM) i7-2820QM CPU @ 2.30GHz
- Intel power meter 报告它 运行在 3.1GHz 时 运行在程序中
- 编译器为 clang++:Apple LLVM 版本 6.0 (clang-600.0.57)(基于 LLVM 3.5svn)
系统B:
- 2 插槽,12 cores/socket 2013 年购买的 Ivy Bridge Xeon 服务器
- 英特尔(R) 至强(R) CPU E5-2697 v2 @ 2.70GHz
- turbostat 报告一个核心 运行ning 在 3.5GHz 时 运行ning 程序
- 编译器是 clang++:Ubuntuclang 版本 3.5-1ubuntu1 (t运行k)(基于 LLVM 3.5)
系统 C:
- 四核 Haswell Core i5
- 英特尔(R) 酷睿(TM) i5-4430 CPU @ 3.00GHz
- turbostat 报告内核最大频率为 3.2GHz
- 编译器为 clang++:clang 版本 3.5.1 (tags/RELEASE_351/final)
您可以在以下位置找到该程序的源代码:http://www.cs.binghamton.edu/~millerti/test.tgz
我在两个系统上使用的编译器命令行如下:
- 标量版本:
clang++ -O3 -msse3 x.c 3_22_1b.c
- 矢量版本:
clang++ -O3 -msse3 x.c 3_22_1.c
这有两件相当奇怪的事情。一是标量版本比矢量版本稍快。但真正巨大的问题是这个程序在服务器(系统B)上运行所花的时间是笔记本(系统A)上的两倍多。
在系统 A 上:
$ time ./a.out
real 0m22.908s
user 0m22.853s
sys 0m0.038s
在系统 B 上:
$ time ./a.out
real 0m55.354s
user 0m55.310s
sys 0m0.000s
在系统 C 上:
$ time ./a.out
real 0m42.421s
user 0m42.400s
sys 0m0.000s
其他事实:
- Sandy Bridge 和 Ivy Bridge 具有相同数量的 L1 缓存(总共 64KB)。其实哈斯韦尔也是。
- 系统 B 的二级缓存比其他任何一个都多
- 可执行文件非常小,应该至少大部分适合 L1I 缓存
- 数据量为176个float,所以L1D缓存命中率应该在100%左右
- IVB 和 SB 微架构非常相似,不同之处主要有利于 IVB
- 正在卸载所有系统 运行。笔记本(系统 A)确实有最少的其他事情在进行。服务器(系统 B)和 Haswell(系统 C)完全卸载。没有其他用户或任何东西。
top
显示程序在所有系统中获得 100% CPU。iotop
显示在此期间服务器上没有 I/O 进行。- 在任何情况下,与 clang 相比,使用 g++ 都没有太大区别。
- 作为参考,我添加了 Haswell,它没有照亮任何东西。这比 Ivy Bridge 快很多但比 Sandy Bridge 慢是没有意义的。
- 操作系统不可能对这里产生任何影响,而且 Apple 不可能在他们尚未共享的 LLVM 编译器中施展某种魔法,使程序运行得更快。
- 我确实尝试过对 tanh 进行基准测试。事实证明,它在 MacOS X 上的速度大约是 Linux 的两倍。 1 亿次 tanh 调用在系统 A (Mac) 上需要 1.484 秒,而在系统 C (Haswell) 上需要 3.380 秒,在系统 B(IVB 服务器)上需要 3.392 秒。不过,我做过profiling,tanh只占总时间的35%左右运行,所以不能解释整个性能差距
-ffast-math
没有帮助。- 我正在 Mac 上的虚拟机中安装 Linux。我将 运行 Linux 和 Mac 上的相同代码,以查看 glibc 的慢数学有多少以及 CPU 有多少。 (由于这是计算密集型,虚拟化无关紧要。)我稍后会添加结果。
您需要检查汇编列表。一个编译器可能会生成 SISD 指令,而另一个 SIMD - 例如 mulss xmm0, xmm7 而不是 mulps xmm0, xmm7,它可以快四倍(在相同的 CPU GHz 下)。然后有AVX指令可以试试。
您描述的问题通常是由较旧的编译器生成的速度最慢引起的,或者就我而言,使用最新的免费 Microsoft 编译器与 Linux 的最新 GCC 相比,后者生成了卓越的实现。
原因完全是tanh
。由于分析开销,分析没有揭示这一点。我不知道为什么我昨晚没有想到这个,但是今天早上,我注释掉了 tanh,这就是我得到的:
系统A:
$ time ./a.out
real 0m4.443s
user 0m4.433s
sys 0m0.008s
系统 B:
$ time ./a.out
real 0m3.373s
user 0m3.368s
sys 0m0.003s
系统 C:
$ time ./a.out
real 0m4.054s
user 0m4.050s
sys 0m0.000s
这些数字都有道理。所以结论是 tanh 的 Linux 实现真的很糟糕。我必须自己实现或从 BSD libc 获取 tanh 源代码。