c++ - 同样的程序在 Linux 上比在 Windows 上运行更快——为什么?

标签 c++ windows linux gcc benchmarking

在问题 Executable runs faster on Wine than Windows -- why? 中找到了对此的

解决方案 Glibc 的 floor() 很可能是以系统库的形式实现的。


我有一个非常小的 C++ 程序(约 100 行)用于物理模拟。我在同一台计算机上的 Ubuntu Oneiric 和 Windows XP 上使用 gcc 4.6.1 编译了它。我使用了完全相同的命令行选项(相同的 makefile)。

奇怪的是,在 Ubuntu 上,程序完成的速度比在 Windows 上快得多(~7.5 秒对 13.5 秒)。在这一点上,我认为这是编译器的差异(尽管使用相同的版本)。

但更奇怪的是,如果我在 wine 下运行 Windows 可执行文件,它仍然比在 Windows 上更快(我得到 11 秒的“真实”时间和 7.7 秒的“用户”时间——这包括 wine 启动。)

我很困惑。当然,如果相同的代码在相同的 CPU 上运行,则时间上应该没有差异。

这可能是什么原因?我可能做错了什么?

该程序执行最少的 I/O(输出一行),并且仅使用来自 STL 的固定长度的 vector(即不应涉及系统库)。在 Ubuntu 上我使用默认的 gcc,在 Windows 上我使用 Nuwen distribution .我在进行基准测试时验证了 CPU 使用率接近于零(我关闭了大多数程序)。在 Linux 上,我使用 time 进行计时。在 Windows 上,我使用了 timethis.exe

更新

我做了一些更精确的计时,比较了 gcc 和 msvc 编译的程序在 Windows XP、Wine 和 Linux 上的不同输入(运行时间必须与输入成正比)的运行时间。所有数字均以秒为单位,并且是至少 3 次运行中的最小值。

在 Windows 上我使用了 timethis.exe (墙时间),在 Linux 和 Wine 上我使用了时间(CPU 时间)。 (timethis.exe 在 Wine 上损坏)我确保没有其他程序在使用 CPU 并禁用了病毒扫描程序。

gcc 的命令行选项是 -march=pentium-m -Wall -O3 -fno-exceptions -fno-rtti(即禁用异常)。

Timings

我们从这些数据中看到了什么:

  1. 差异不是由于进程启动时间,因为运行时间与输入成正比

  2. 在 Wine 和 Windows 上运行的区别只存在于 gcc 编译的程序,而不是 msvc 编译的程序:它不会被其他程序占用 Windows 上的 CPU 或 timethis.exe 被破坏所引起.

最佳答案

您会对涉及的系统库感到惊讶。只需在您的应用程序上执行 ldd,然后查看使用了哪些(好的,不是那么多,但肯定是 glibc)。

为了完全相信您关于执行速度的发现,您需要按顺序运行您的应用几次并计算平均执行时间。可能是操作系统加载器速度较慢(尽管 4 秒是一个较长的加载时间)。

其他很可能的原因是:

  1. 不同的 malloc 实现
  2. 异常处理,如果过度使用可能会导致速度下降(Windows GCC、MinGW 可能不是最佳的异常处理明星)
  3. 依赖于操作系统的初始化:在 Windows 上程序启动时需要完成的事情,但在 Linux 上则不需要。

其中大部分都可以轻松进行基准测试 ;-)


更新您的更新:您现在唯一能做的就是配置文件。停止猜测,让分析器告诉您时间花在了哪里。使用 gprof 和 Visual Studio 内置分析器并比较在不同函数上花费的时间。

关于c++ - 同样的程序在 Linux 上比在 Windows 上运行更快——为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8071851/

相关文章:

c++ - 在 cmake 中,cmake 文件夹和 CMakeLists.txt 可以放在不同的文件夹中吗?

windows - 为什么特定站点上的 HTTP/2 在 FF 中有效,但在同一台 Windows 10 计算机上的 Chrome、IE 和 Edge 中却无效?

php - 有经验的 Asp.net 程序员在开始使用 PHP 时应该了解什么?

windows - 如何在批处理脚本中的多个文件上重命名和添加递增数字后缀?

c++ - 此应用程序无法启动,因为它无法在 "xcb"中找到或加载 Qt 平台插件 ""。并且找不到/usr/lib/qt5

linux - bash 中的旧 csh 别名

c++ - 插入一个元素到柠檬图库 map 而不复制

c++ - boost序列化实际上是如何保存const对象的

c++ - LoadLibrary 的 STATUS_STACK_BUFFER_OVERRUN

linux - Zabbix-添加脚本参数触发