Same program faster on Linux than Windows — why?

2019-01-28 01:05发布

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.

3条回答
女痞
2楼-- · 2019-01-28 01:51

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

查看更多
干净又极端
3楼-- · 2019-01-28 01:58

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.

查看更多
放荡不羁爱自由
4楼-- · 2019-01-28 02:04

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.

查看更多
登录 后发表回答