Скорость работы программы Qt: Windows vs Linux - программирование
Подтвердить что ты не робот

Скорость работы программы Qt: Windows vs Linux

Я уже разместил этот вопрос здесь, но, поскольку он, возможно, не тот Qt-специфический, я думал, что могу попробовать свой шанс здесь, Что ж. Я надеюсь, что это не неуместно делать (просто скажите, если это так).

Я разработал небольшую научную программу, которая выполняет некоторые математические вычисления. Ive попытался оптимизировать его так, чтобы он был как можно быстрее. Теперь Im почти выполнил развертывание для пользователей Windows, Mac и Linux. Но я еще не смог протестировать его на разных компьютерах.

Вот что меня беспокоит: для развертывания для Windows Ive использовал ноутбук, на котором установлены как Windows 7, так и Ubuntu 12.04 (двойная загрузка). Я сравнил скорость приложения, работающего на этих двух системах, и я был потрясен, заметив, что его, по крайней мере, в два раза медленнее в Windows! Я бы не удивился, если бы была небольшая разница, но как можно ли объяснить такую ​​разницу?

Вот несколько замечаний:

  • Вычисление, которое я делаю в программе, - это лишь некоторые жестокие и глупые математические вычисления, в основном, он вычисляет продукты и косинусы в цикле, который называется миллиардом раз. С другой стороны, вычисление многопоточное: я запускаю что-то вроде 6 QThreads.
  • Ноутбук имеет два ядра: 1.73 ГГц. Сначала я подумал, что Windows, вероятно, не использует один из ядер, но затем я посмотрел на активность процессора, согласно небольшой графике, оба ядра работают на 100%.
  • Тогда я подумал, что компилятор С++ для Windows не использовал параметры оптимизации (например, -O1-O2), которые компилятор С++ для Linux автоматически выполнял (в версии сборки), но, по-видимому, это делает.

Мне показалось, что приложение настолько медленнее (от 2 до 4 раз) в Windows, и это действительно странно. С другой стороны, я еще не пытался на других компьютерах с Windows. Тем не менее, вы не знаете, почему разница?

Дополнительная информация: некоторые данные...

Хотя Windows, похоже, использует два ядра, Im думает, что это может иметь отношение к управлению потоками, почему:

Пример вычисления n ° 1 (этот запуск запускает 2 QThreads):

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

Пример вычисления n ° 2 (этот запуск запускает 3 QThreads):

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

Пример вычисления n ° 3 (этот запуск запускает 6 QThreads):

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

где:

  • PC1-windows = мой 2-ядерный ноутбук (@1.73Ghz) с Windows 7
  • PC1-linux = мой 2-ядерный ноутбук (@1.73Ghz) с Ubuntu 12.04
  • PC2-linux = мой 8-ядерный ноутбук (@2.20Ghz) с Ubuntu 12.04

(Конечно, это не шокирует, что PC2 работает быстрее. Для меня невероятно отличие между PC1-окнами и PC1-Linux).

Примечание. Я также попытался запустить программу на недавнем ПК (4 или 8 ядер @~ 3Ghz, не помню точно) в Mac OS, скорость была сопоставима с PC2-linux (или немного быстрее).

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

  • Я только что установил Qt SDK в Windows, поэтому, я думаю, у меня есть последняя версия всего (включая MinGW?). Компилятор MinGW. Версия Qt - 4.8.1.

  • Я не использую флаги оптимизации, потому что заметил, что они автоматически используются при создании в режиме выпуска (с Qt Creator). Мне кажется, что если я пишу что-то вроде QMAKE_CXXFLAGS + = -O1, это только влияет на сборку отладки.

  • Время жизни и т.д.: это довольно просто. Когда пользователь нажимает кнопку "Вычислить", одновременно запускается от 2 до 6 потоков (в зависимости от того, что он вычисляет), они заканчиваются, когда вычисление завершается. Ничего особенного. Каждый поток просто выполняет брутальные вычисления (за исключением одного, фактически, который делает (не очень) "маленькое" вычисление каждые 30 мс, в основном проверяя, достаточно ли ошибка.)

EDIT: последние разработки и частичные ответы

Вот некоторые новые разработки, которые дают ответы обо всем этом:

  • Я хотел определить, действительно ли разница в скорости имела какое-то отношение к потокам или нет. Поэтому я модифицировал программу так, что в вычислении используется только 1 поток, таким образом мы в значительной степени сравниваем производительность с "чистым кодом на С++". Оказалось, что теперь Windows немного медленнее, чем Linux (примерно 15%). Поэтому я полагаю, что небольшая (но не несущественная) часть разницы является неотъемлемой частью системы, но самая большая часть связана с управлением потоками.

  • Как сказал в комментариях (Luca Carlon, спасибо за это), я попытался создать приложение с помощью компилятора для Microsoft Visual Studio (MSVC) вместо MinGW. И suprise, вычисление (со всеми нитями и всем) теперь было "всего" на 20-50% медленнее, чем Linux! Думаю, я собираюсь идти вперед и быть довольным этим. Я заметил, что странно, что вычисление "чистого С++" (только с одним потоком) стало еще медленнее (чем с MinGW), что должно учитывать общую разницу. Насколько я могу судить, MinGW немного лучше, чем MSVC, за исключением того, что он обрабатывает потоки, такие как придурок.

Итак, я думаю, что я могу сделать что-то, что я могу сделать, чтобы сделать MinGW (в идеале Id скорее использовать его, чем MSVC) лучше обрабатывать потоки, или это просто невозможно. Я был бы поражен, как бы это не было хорошо известно и задокументировано? Хотя я думаю, что я должен быть осторожным в том, чтобы делать выводы слишком быстро, но я только сравнивал вещи на одном компьютере (на данный момент).

4b9b3361

Ответ 1

Другим вариантом может быть: на linux qt только что загружены, это может произойти, если вы используете KDE, в то время как в библиотеке Windows должны быть загружены, чтобы это замедляло время вычисления. Чтобы проверить, сколько загрузок библиотеки загружает ваше приложение, вы можете написать фиктивный тест с чистым кодом С++.

Ответ 2

Я слышал об одном случае, когда Windows очень медленно записывала файлы, если вы делаете это неправильно. (Это не имеет ничего общего с Qt.)

В этом случае проблема заключалась в том, что разработчик использовал базу данных SQLite, написал около 10000 наборов данных и выполнил SQL COMMIT после каждой вставки. Это заставило Windows записывать весь файл DB на диск каждый раз, в то время как Linux только обновил буферизованную версию inode файловой системы в ОЗУ. В этом случае разница в скорости была еще хуже: 1 секунда в Linux против 1 минуты в Windows. (После того, как он сменил SQLite на фиксацию только один раз в конце, он был также 1 секундой для Windows.)

Итак, если вы пишете результаты ваших вычислений на диск, вы можете проверить, часто ли вы вызываете fsync() или fflush(). Если ваш код написан из библиотеки, вы можете использовать strace для этого (только для Linux, но должны дать вам базовую идею).

Ответ 3

У вас могут возникнуть различия в производительности, связанные с использованием мьютексов в Windows и Linux.

Чистый код мьютекса в окнах может иметь 15 мс ожидания каждый раз, когда есть конкуренция за ресурс при блокировке. Улучшенный механизм синхронизации в Windows - Критические разделы. Он не испытывает штраф за блокировку, который в большинстве случаев испытывает обычные мьютексы.

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

Ответ 4

Возможно, это распределитель памяти, попробуйте использовать jemalloc или tcmalloc от Google. Glibc ptmalloc3 значительно лучше, чем старый crusty allocator в MSVC crt. Сравнимым вариантом из Microsoft является Concurrency CRT, но вы не можете просто отказаться от него в качестве замены.

Ответ 5

Я заметил точно такое же поведение на моем ПК. Я запускаю Windows 7 (64 бита), Ubuntu (64 бит) и OSX (Lion 64bits), и моя программа сравнивает 2 файла XML (более 60 Мб каждый). Он также использует многопоточность (2 потока):

-Windows : 40sec

-Linux : 14sec (!!!)

-OSX : 22sec.

Я использую персональный класс для потоков (а не Qt one), который использует "pthread" для linux/OSX и "threads" в окнах. Я использую компилятор Qt/mingw, поскольку мне нужен класс XML из Qt.

Я не нашел способа (на данный момент) иметь 3 ОС с похожими характеристиками... но я надеюсь, что буду!

Я думаю, что другой причиной может быть память: моя программа использует около 500 МБ ОЗУ. Поэтому я думаю, что Unix лучше управляет этим, потому что в монопотоке Windows в 1,89 раза медленнее, и я не думаю, что Linux может быть более чем в 2 раза медленнее!