Одна и та же программа в Linux работает быстрее, чем в Windows, почему?

Решение этой проблемы было найдено в вопросе Исполняемый файл в Wine работает быстрее, чем в Windows - почему? Glibc floor(), вероятно, реализован в виде системных библиотек.


У меня есть очень маленькая программа на C ++ (~ 100 строк) для моделирования физики. Я скомпилировал его с помощью gcc 4.6.1 как на Ubuntu Oneiric, так и на Windows XP на одном компьютере. Я использовал точно такие же параметры командной строки (тот же файл makefile).

Как ни странно, в Ubuntu программа завершается намного быстрее, чем в Windows (~ 7,5 с против 13,5 с). На данный момент я подумал, что это разница между компиляторами (несмотря на то, что используется одна и та же версия).

Но что еще более странно, если я запускаю исполняемый файл Windows под вином, он все равно быстрее, чем в Windows (я получаю 11 с «реальное» и 7,7 с «пользовательское» время - и это включает винный запуск).

Я запутался. Конечно, если один и тот же код выполняется на одном и том же процессоре, не должно быть разницы во времени.

В чем может быть причина этого? Что я делаю не так?

Программа выполняет минимальный ввод-вывод (выводит одну строку) и использует только vector фиксированной длины из STL (т.е. никакие системные библиотеки не должны использоваться). В Ubuntu я использовал gcc по умолчанию, а в Windows - дистрибутив Nuwen. Я проверил, что загрузка ЦП близка к нулю при проведении бенчмаркинга (я закрыл большинство программ). В Linux я использовал time для измерения времени. В Windows я использовал timethis.exe.

ОБНОВЛЕНИЕ

Я сделал несколько более точных таймингов, сравнив время работы для разных входов (время выполнения должно быть пропорционально входу) программ, скомпилированных с помощью gcc и msvc, в Windows XP, Wine и Linux. Все числа указаны в секундах и являются минимумом из 3 прогонов.

В Windows я использовал timethis.exe (настенное время ), в Linux и Wine я использовал время (процессорное время). (timethis.exe не работает в Wine) Я убедился, что никакие другие программы не используют ЦП, и отключил антивирусный сканер.

Параметры командной строки для gcc были -march=pentium-m -Wall -O3 -fno-exceptions -fno-rtti (т.е. исключения были отключены).

Время

Что мы видим из этих данных:

  1. разница не связана со временем запуска процесса, поскольку время выполнения пропорционально вводу

  2. Разница между запуском в Wine и Windows существует только для программы, скомпилированной с помощью gcc, а не для программы, скомпилированной с помощью msvc: это не может быть вызвано другими программами, загружающими процессор в Windows, или нарушением timethis.exe.


person Szabolcs    schedule 09.11.2011    source источник
comment
Сколько памяти использует эта штука? Вы пробовали запускать его под профилировщиком?   -  person bdonlan    schedule 10.11.2011
comment
Это как сказать, если две разные машины (грузовик и маленькая спортивная машина) используют один и тот же двигатель, они должны ускоряться с одинаковой скоростью?   -  person CrazyDart    schedule 10.11.2011
comment
Может быть, на Windows время запуска больше? Если вы заставите программу работать дольше, как это повлияет на разницу во времени между Windows и Linux?   -  person celtschk    schedule 10.11.2011
comment
@bdonlan По данным Process Explorer, он использует менее 1 МБ.   -  person Szabolcs    schedule 10.11.2011
comment
@celtschk Я проверю. Я не могу ответить быстро, потому что мне нужно снова перезагрузить компьютер для тестирования в Linux.   -  person Szabolcs    schedule 10.11.2011
comment
Вы также должны протестировать MSVC в Windows, он, вероятно, будет быстрее, чем GCC, являющийся собственным компилятором (в некоторых случаях MSVC, созданный под Win, даже быстрее, чем GCC под nix). Если вам это удастся, попробуйте также ICC.   -  person ssube    schedule 10.11.2011
comment
@peachykeen Я пробовал компилятор из VC ++ Express 2010, который дает мне около 11,5 с. Я также должен попробовать скомпилированный исполняемый файл MSVC в Wine.   -  person Szabolcs    schedule 10.11.2011
comment
Еще одна мысль: вы измеряли время процессора или время на стене? В последнем случае это могут быть просто фоновые процессы, запущенные в Windows и отнимающие циклы процессора (например, некоторая антивирусная программа).   -  person celtschk    schedule 10.11.2011
comment
Включена ли у вас какая-либо оптимизация в любом из компиляторов?   -  person ssube    schedule 10.11.2011
comment
@celtschk Пожалуйста, посмотрите мое обновление в посте, оно ответит на ваши вопросы.   -  person Szabolcs    schedule 10.11.2011


Ответы (3)


Вы будете удивлены, какие системные библиотеки задействованы. Просто выполните ldd в своем приложении и посмотрите, какие из них используются (хорошо, не так уж много, но определенно glibc).

Чтобы полностью доверять своим выводам о скорости выполнения, вам нужно будет запустить приложение несколько раз подряд и взять среднее время выполнения. Возможно, загрузчик ОС работает медленнее (хотя 4 секунды - это долгое время загрузки).

Другие очень возможные причины:

  1. Другая реализация malloc
  2. Обработка исключений, если ее использовать в крайнем случае, может вызвать замедление (Windows GCC, MinGW, возможно, не лучшая звезда обработки исключений в шоу)
  3. Инициализация, зависящая от ОС: то, что нужно делать при запуске программы в Windows, но не в Linux.

Большинство из них легко протестировать ;-)


Обновление вашего обновления: единственное, что вы теперь можете сделать, это профиль. Перестаньте гадать и позвольте профилировщику сказать вам, на что вы тратите время. Используйте gprof и встроенный профилировщик Visual Studio и сравните время, потраченное на разные функции.

person rubenvb    schedule 09.11.2011
comment
Я запускал его много раз, чтобы убедиться, что время правильное (я изучал физику, поэтому выучил урок во время лабораторных занятий). Хорошо, поэтому сначала я увеличу время однократного выполнения до более чем минуты, я отключу исключения (я их не использую), буду использовать массив в стиле C вместо std::vector, чтобы избавиться от всех malloc / новый, то попробую еще раз. Это займет некоторое время, так как мне тоже нужно перезагрузиться. - person Szabolcs; 10.11.2011
comment
Пожалуйста, посмотрите мою редакцию вопроса. Я исключил пункты 2. и 3. Пункт 1. все еще возможен, но насколько я понимаю, моя программа не должна выделять память в куче, кроме как при запуске, когда инициализируется std::vector. - person Szabolcs; 10.11.2011

Проведите сравнительный анализ кода. Также попробуйте скомпилировать с помощью Visual Studio. В Windows, если у вас есть какое-то приложение, такое как Yahoo Messenger, которое устанавливает хуки, они могут очень легко замедлить время загрузки вашего приложения.

В Windows у вас есть: QueryPerformanceCounter В Linux: clock_gettime

person neagoegab    schedule 09.11.2011

Видимо разница связана с системой.

Вы можете использовать strace, чтобы понять, какие системные вызовы выполняются, например

strace -o /tmp/yourprog.tr yourprog

а затем загляните в /tmp/yourprog.tr

(Если эквивалент strace существовал в Windows, попробуйте его использовать)

Возможно, ваша программа выделяет память (используя системный вызов mmap), и, возможно, системные вызовы, связанные с памятью, выполняются быстрее в Linux (или даже в Wine), чем в Windows? Или некоторые другие системные вызовы обеспечивают более быструю функциональность в Linux, чем в Windows.

NB. Я ничего не знаю о Windows, так как использую системы Unix с 1986 года и Linux с 1993 года.

person Basile Starynkevitch    schedule 09.11.2011
comment
Я попробую это. Что касается вашего редактирования заголовка, есть разница и для одного и того же исполняемого файла, запускаемого либо в Windows, либо в Wine (а не только тогда, когда исходный код скомпилирован в разных системах). Что для меня действительно странно. - person Szabolcs; 10.11.2011
comment
Когда вы используете Wine, вы косвенно используете ядро ​​Linux. Так что это не так уж и странно (и с Wine, и под Linux вы используете одно и то же ядро). - person Basile Starynkevitch; 10.11.2011