【问题标题】:Speed performance of a Qt program: Windows vs LinuxQt 程序的速度性能:Windows 与 Linux
【发布时间】:2012-10-04 10:40:06
【问题描述】:

我已经发布了这个问题here,但由于它可能不是特定于 Qt 的,所以我想我也可以在这里试试我的机会。我希望这样做不是不合适的(如果是,请告诉我)。

我开发了一个小型科学程序,可以执行一些数学计算。我已经尝试对其进行优化,以使其尽可能快。现在我几乎完成了为 Windows、Mac 和 Linux 用户部署它。但是我还不能在很多不同的计算机上测试它。

让我感到困扰的是:为了部署 Windows,我使用了一台同时安装了 Windows 7 和 Ubuntu 12.04 的笔记本电脑(双启动)。我比较了在这两个系统上运行的应用程序的速度,我震惊地发现 它在 Windows 上至少慢了一倍!如果有一点点差异,我不会感到惊讶,但是如何解释这样的差异呢?

以下是一些精度:

  • 我让程序做的计算只是一些残酷而愚蠢的数学计算,基本上,它在一个称为十亿次的循环中计算乘积和余弦。另一方面,计算是多线程的:我启动了类似 6 个 QThreads 的东西。
  • 笔记本电脑有两个内核@1.73Ghz。起初我以为 Windows 可能没有使用其中一个内核,但后来我查看了处理器活动,根据小图,两个内核都在 100% 运行。
  • 然后我认为适用于 Windows 的 C++ 编译器没有使用适用于 Linux 的 C++ 编译器自动执行的优化选项(如 -O1 -O2),但显然确实如此。

我很烦恼这个应用在 Windows 上的速度太慢了(2 到 4 倍),这真的很奇怪。另一方面,我还没有在其他装有 Windows 的计算机上尝试过。不过,您知道为什么会有差异吗?

附加信息:一些数据……

尽管 Windows 似乎使用两个内核,但我认为这可能与线程管理有关,原因如下:

示例计算 n°1(这个启动 2 个 QThreads):

  • PC1-windows:7.33s
  • PC1-linux:3.72s
  • PC2-linux:1.36s

Sample Computation n°2(这个启动 3 个 QThreads):

  • PC1-windows:6.84s
  • PC1-linux:3.24s
  • PC2-linux:1.06s

Sample Computation n°3(这个启动 6 个 QThreads):

  • PC1-windows:8.35s
  • PC1-linux:2.62s
  • PC2-linux:0.47s

地点:

  • PC1-windows = 我的装有 Windows 7 的 2 核笔记本电脑 (@1.73Ghz)
  • PC1-linux = 我的 Ubuntu 12.04 的 2 核笔记本电脑 (@1.73Ghz)
  • PC2-linux = 我的 8 核笔记本电脑 (@2.20Ghz) 和 Ubuntu 12.04

(当然,PC2的速度更快并不令人震惊。让我难以置信的是PC1-windows和PC1-linux之间的区别)。

注意:我还尝试在最近的 PC(4 或 8 核 @~3Ghz,不记得确切)上在 Mac OS 下运行该程序,速度与 PC2-linux 相当(或略快)。

编辑:我将在这里回答我在 cmets 中被问到的几个问题。

  • 我刚刚在 Windows 上安装了 Qt SDK,所以我想我拥有所有东西的最新版本(包括 MinGW?)。编译器是 MinGW。 Qt 版本是 4.8.1。

  • 我没有使用优化标志,因为我注意到当我以发布模式(使用 Qt Creator)构建时它们会自动使用。在我看来,如果我写像 QMAKE_CXXFLAGS += -O1 这样的东西,这只对调试版本有影响。

  • 线程的生命周期等:这很简单。当用户单击“计算”按钮时,会同时启动 2 到 6 个线程(取决于他正在计算的内容),当计算结束时它们将被终止。没什么太花哨的。每个线程都只是进行残酷的计算(实际上除了一个,它每 30 毫秒进行一次(不是那么小)计算,主要是检查错误是否足够小)。

编辑:最新进展和部分答案

这里有一些新的发展可以为这一切提供答案:

  • 我想确定速度差异是否真的与线程有关。所以我修改了程序,使计算只使用 1 个线程,这样我们就可以比较“纯 C++ 代码”的性能。事实证明,现在 Windows 只比 Linux 慢一点(大约 15%)。所以我猜差异的一小部分(但并非不重要)是系统固有的,但最大的部分是由于线程管理

  • 正如 cmets 中的某个人(Luca Carlon,感谢您)所建议的那样,我尝试使用 Microsoft Visual Studio (MSVC) 的编译器而不是 MinGW 来构建应用程序。令人惊讶的是,计算(包含所有线程和所有内容)现在“仅”比 Linux 慢 20% 到 50%!我想我会继续前进并对此感到满意。我注意到奇怪的是,“纯 C++”计算(只有一个线程)现在甚至更慢(比使用 MinGW),这必须解释整体差异。据我所知,MinGW 比 MSVC 稍好一点,只是它处理线程的方式像个白痴

所以,我在想要么我可以做一些事情来让 MinGW(我宁愿使用它而不是 MSVC)更好地处理线程,或者它不能。我会很惊讶,它怎么可能不为人所知和记录在案?虽然我想我应该小心不要太快得出结论,但我只在一台计算机上进行了比较(目前)。

【问题讨论】:

  • 嗯,很有可能因为 Qt 是在 UNIX 系统上为 pthread 设计的,所以它在 Win32 上的实现并不那么好。
  • 我相信你必须手动启用windows线程kde.gr.jp/~ichi/qt/threads.html,你这样做了吗?
  • @jozefg:我没有意识到这一点。但这是我在官方文档中读到的内容:(doc.qt.digia.com/qt/threads.html) “Qt 的早期版本提供了一个选项来构建不支持线程的库。从 Qt 4.0 开始,线程始终处于启用状态。”我的意思是,我确定多线程正在工作(否则计算将无法工作),但效果如何,我不知道。我什至不知道这种性能对比是否真的是由于多线程造成的。
  • 可能是,嗯,你有没有通过分析器运行它来检查慢的部分在哪里?
  • 您可以尝试使用microsoft visual studio 编译器进行编译并查看结果。

标签: c++ windows linux performance qt


【解决方案1】:

另一个选项可能是:在 linux 上,qt 刚刚加载,这可能会发生,即如果您使用 KDE,而在 Windows 中必须加载库,这样会减慢计算时间。要检查有多少库加载浪费了您的应用程序,您可以使用纯 C++ 代码编写一个虚拟测试。

【讨论】:

  • 感谢您的建议,请参阅我的初始帖子的最新编辑以获取最新发展和部分答案。
【解决方案2】:

我听说过一种情况,如果操作不当,Windows 写入文件的速度会非常慢。 (这与Qt无关。)

在这种情况下的问题是,开发人员使用 SQLite 数据库,编写了大约 10000 个数据集,并在每次插入后执行 SQL COMMIT。这导致 Windows 每次都将整个 DB 文件写入磁盘,而 Linux 只会更新 RAM 中文件系统 inode 的缓冲版本。在这种情况下,速度差异甚至更糟:Linux 上为 1 秒,而 Windows 上为 1 分钟。 (他把 SQLite 改成最后只提交一次后,在 Windows 上也是 1 秒。)

因此,如果您将计算结果写入磁盘,您可能需要检查是否过于频繁地调用fsync()fflush()。如果您的编写代码来自库,您可以使用 strace 来实现这一点(仅限 Linux,但应该会给您一个基本的概念)。

【讨论】:

  • 感谢您的关注和分享您的知识。我相信在我的情况下,解释主要是在线程管理中找到的:请参阅我最新的编辑(有问题)以获取最新的发展和部分答案。
【解决方案3】:

您可能会因互斥锁在 Windows 和 Linux 上的运行方式而遇到性能差异。

Windows 上的纯互斥代码在锁定时每次发生资源争用时可能需要等待 15 毫秒。在 Windows 上性能更好的同步机制是Critical Sections。在大多数情况下,它不会像常规互斥锁那样经历锁定惩罚。

我发现在 Linux 上,常规互斥锁的性能与 Windows 上的关键部分相同。

【讨论】:

  • 自适应互斥体,即由自旋锁包裹的互斥体在许多情况下会更好。适用于 Windows 和 Linux。
【解决方案4】:

这可能是内存分配器,尝试使用来自 Google 的 jemalloctcmalloc。 Glibc 的 ptmalloc3 明显优于 MSVC 的 crt 中旧的硬壳分配器。来自 Microsoft 的类似选项是 Concurrency CRT,但您不能简单地将其作为替代品。

【讨论】:

    【解决方案5】:

    我注意到我的 PC 上的行为完全相同。 我正在运行 Windows 7(64 位)、Ubuntu(64 位)和 OSX(Lion 64 位),我的程序比较了 2 个 XML 文件(每个文件超过 60Mb)。它也使用多线程(2 个线程):

    -Windows : 40sec
    
    -Linux : 14sec (!!!)
    
    -OSX : 22sec.
    

    我使用个人线程类(而不是 Qt 类),它在 linux/OSX 上使用“pthread”,在 Windows 上使用“threads”。 我使用 Qt/mingw 编译器,因为我需要来自 Qt 的 XML 类。

    我(目前)没有办法让这 3 个操作系统具有相似的性能......但我希望我能做到!

    我认为另一个原因可能是内存:我的程序使用了大约 500Mb 的 RAM。所以我认为 Unix 管理得最好,因为在单线程中,Windows 正好慢 1.89 倍,我不认为 Linux 可以慢 2 倍以上!

    【讨论】:

      猜你喜欢
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 2010-11-23
      • 1970-01-01
      • 2013-12-19
      相关资源
      最近更新 更多