同样的程序在 Linux 上比 Windows 上更快——为什么?

发布于 2024-12-14 08:12:44 字数 1701 浏览 1 评论 0原文

解决方案可以在问题中找到可执行文件在 Wine 上的运行速度比 Windows 上快——为什么? Glibc 的 floor() 可能是通过系统库实现的。


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

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

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

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

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

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

更新

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

在 Windows 上,我使用 timethis.exe ( wall time),在 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被破坏不会导致这种情况。

The solution to this was found in the question Executable runs faster on Wine than Windows -- why? Glibc's floor() is probably implemented in terms of system libraries.


I have a very small C++ program (~100 lines) for a physics simulation. I have compiled it with gcc 4.6.1 on both Ubuntu Oneiric and Windows XP on the same computer. I used precisely the same command line options (same makefile).

Strangely, on Ubuntu, the program finishes much faster than on Windows (~7.5 s vs 13.5 s). At this point I thought it's a compiler difference (despite using the same version).

But even more strangely, if I run the Windows executable under wine, it's still faster than on Windows (I get 11 s "real" and 7.7 s "user" time -- and this includes wine startup.)

I'm confused. Surely if the same code is run on the same CPU, there shouldn't be a difference in the timing.

What can be the reason for this? What could I be doing wrong?

The program does minimal I/O (outputs a single line), and only uses a fixed-length vector from the STL (i.e. no system libraries should be involved). On Ubuntu I used the default gcc and on Windows the Nuwen distribution. I verified that the CPU usage is close to zero when doing the benchmarking (I closed most programs). On Linux I used time for timing. On Windows I used timethis.exe.

UPDATE

I did some more precise timings, comparing the running time for different inputs (run-time must be proportional to the input) of the gcc and msvc-compiled programs on Windows XP, Wine and Linux. All numbers are in seconds and are the minimum of at least 3 runs.

On Windows I used timethis.exe (wall time), on Linux and Wine I used time (CPU time). (timethis.exe is broken on Wine) I made sure no other programs were using the CPU and disabled the virus scanner.

The command line options to gcc were -march=pentium-m -Wall -O3 -fno-exceptions -fno-rtti (i.e. exceptions were disabled).

Timings

What we see from this data:

  1. the difference is not due to process startup time, as run-times are proportional to the input

  2. The difference between running on Wine and Windows exists only for the gcc-compiled program, not the msvc-compiled one: it can't be casued by other programs hogging the CPU on Windows or timethis.exe being broken.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

哎呦我呸! 2024-12-21 08:12:44

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

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

其他很可能的原因是:

  1. 不同的 malloc 实现
  2. 异常处理,如果使用到极端可能会导致速度变慢(Windows GCC、MinGW,可能不是最佳的异常处理明星)
  3. 操作系统相关的初始化:需要在程序在 Windows 上启动,但在 Linux 上无法启动。

其中大多数都很容易进行基准测试;-)


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

You'd be surprised what system libraries are involved. Just do ldd on your app, and see which are used (ok, not that much, but certainly glibc).

In order to completely trust your findings about execution speed, you would need to run your app a couple of times sequentially and take the mean execution time. It might be that the OS loader is just slower (although 4s is a long loading time).

Other very possible reasons are:

  1. Different malloc implementation
  2. Exception handling, if used to the extreme might cause slowdown (Windows GCC, MinGW, might not be the optimal exception handling star of the show)
  3. OS-dependent initialization: stuff that needs to be done at program startup on Windows, but not on Linux.

Most of these are easily benchmarkable ;-)


An update to your update: the only thing you can now do is profile. Stop guessing, and let a profiler tell you where time is being spent. Use gprof and the Visual Studio built-in profiler and compare time spent in different functions.

中性美 2024-12-21 08:12:44

在代码中进行基准测试。也尝试使用 Visual Studio 进行编译。在 Windows 上,如果您有一些应用程序(例如 Yahoo Messenger)正在安装挂钩,它们可以很容易地减慢应用程序的加载时间。

在 Windows 上,您有: QueryPerformanceCounter
在 Linux 上:clock_gettime

Do benchmarking in code. Also try to compile with visual studio. On windows if you have some application like Yahoo Messenger, that are installing hooks, they can very easy slow down your application loading times.

On windows you have: QueryPerformanceCounter
On Linux: clock_gettime

痞味浪人 2024-12-21 08:12:44

显然差异与系统有关。

您可以使用 strace 来了解系统调用的执行情况,例如

strace -o /tmp/yourprog.tr yourprog

,然后查看 /tmp/yourprog.tr

(如果与 strace 等效) Windows 上存在,请尝试使用它)

也许您的程序正在分配内存(使用 mmap 系统调用),并且也许与内存相关的系统调用在 Linux(甚至在 Wine)上比在 Windows 上更快?或者其他一些系统调用在 Linux 上提供比 Windows 更快的功能。

注意。我对 Windows 一无所知,因为我从 1986 年开始使用 Unix 系统,从 1993 年开始使用 Linux。

Apparently the difference is system related.

You might use strace to understand what system calls are done, eg

strace -o /tmp/yourprog.tr yourprog

and then look into /tmp/yourprog.tr

(If an equivalent of strace existed on Windows, try to use it)

Perhaps your program is allocating memory (using mmap system call), and perhaps the memory related system calls are faster on Linux (or even on Wine) than on Windows? Or some other syscalls give faster functionality on Linux that on Windows.

NB. I know nothing about Windows, since I'm using Unix systems since 1986 and Linux since 1993.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文