Как заставить Windows работать так же быстро, как Linux для компиляции C ++? - PullRequest
138 голосов
/ 02 августа 2011

Я знаю, что это не столько вопрос программирования, сколько вопрос.

Я работаю над довольно большим кроссплатформенным проектом . В Windows я использую VC ++ 2008. В Linux я использую gcc. В проекте около 40 тыс. Файлов. Windows компилирует и связывает один и тот же проект в 10–40 раз медленнее, чем Linux. Как я могу это исправить?

Одна инкрементная сборка за 20 секунд в Linux и> 3 минуты в Windows. Зачем? Я даже могу установить компоновщик 'gold' в Linux и сократить это время до 7 секунд.

Аналогично, git в 10–40 раз быстрее в Linux, чем в Windows.

В случае с git возможно, что git использует не Windows оптимальным образом, а VC ++? Вы могли бы подумать, что Microsoft захочет сделать своих собственных разработчиков максимально продуктивными, и более быстрая компиляция будет иметь большое значение для этого. Может быть, они пытаются убедить разработчиков в C #?

В качестве простого теста найдите папку с множеством подпапок и выполните простой

dir /s > c:\list.txt

в Windows. Сделайте это дважды и время второго запуска, чтобы он запускался из кэша. Скопируйте файлы в Linux и выполните 2 одинаковых прогона, а второй раз запустите.

ls -R > /tmp/list.txt

У меня есть 2 рабочие станции с точно такими же характеристиками. HP Z600s с 12 ГБ оперативной памяти, 8 ядер на 3,0 ГГц. Для папки с ~ 400k файлами Windows занимает 40 секунд, Linux занимает <1 секунду. </p>

Можно ли настроить реестр для ускорения работы Windows? Что дает?


Несколько слегка релевантных ссылок, относящихся ко времени компиляции, необязательно ввода / вывода.

Ответы [ 13 ]

32 голосов
/ 02 августа 2011

Если не придет хардкорный хакер Windows, вы не получите больше, чем партизанские комментарии (что я не буду делать) и спекуляции (что я и собираюсь попробовать).*

Файловая система - вы должны попробовать те же операции (включая dir) на той же файловой системе.Я сталкивался с этим , который измеряет несколько файловых систем для различных параметров.

Кэширование.Однажды я попытался запустить компиляцию в Linux на RAM-диске и обнаружил, что это медленнее, чем запуск на диске благодаря тому, как ядро ​​заботится о кэшировании.Это серьезный аргумент в пользу Linux и может быть причиной столь разной производительности.

Неверные спецификации зависимостей в Windows.Может быть, спецификации зависимости хрома для Windows не так корректны, как для Linux.Это может привести к ненужным компиляциям, когда вы вносите небольшие изменения.Вы можете проверить это, используя тот же набор инструментов компилятора в Windows.

28 голосов
/ 26 декабря 2011

Несколько идей:

  1. Отключить 8,3 имени. Это может иметь большое значение для дисков с большим количеством файлов и относительно небольшим количеством папок: fsutil behavior set disable8dot3 1
  2. Используйте больше папок. По моему опыту, NTFS начинает замедляться с более чем 1000 файлов в папке.
  3. Включить параллельные сборки с MSBuild; просто добавьте ключ «/ m», и он автоматически запустит одну копию MSBuild для каждого ядра процессора.
  4. Поместите ваши файлы на SSD - очень помогает при случайном вводе / выводе.
  5. Если ваш средний размер файла намного превышает 4 КБ, рассмотрите возможность перестройки файловой системы с большим размером кластера, который приблизительно соответствует вашему среднему размеру файла.
  6. Убедитесь, что файлы были дефрагментированы. Фрагментированные файлы приводят к большому количеству обращений к диску, что может увеличить пропускную способность в 40 и более раз. Используйте утилиту «contig» от sysinternals или встроенный дефрагментатор Windows.
  7. Если ваш средний размер файла небольшой, а раздел, на котором вы находитесь, относительно полон, возможно, вы работаете с фрагментированным MFT, что плохо сказывается на производительности. Кроме того, файлы размером менее 1 КБ хранятся непосредственно в MFT. Упомянутая выше утилита "contig" может помочь, или вам может потребоваться увеличить размер MFT. Следующая команда удвоит его до 25% от объема: fsutil behavior set mftzone 2 Измените последнее число на 3 или 4, чтобы увеличить размер на дополнительные 12,5% приращения. После выполнения команды перезагрузите компьютер и создайте файловую систему.
  8. Отключить время последнего доступа: fsutil behavior set disablelastaccess 1
  9. Отключить службу индексирования
  10. Отключите антивирусное и антишпионское программное обеспечение или, по крайней мере, установите соответствующие папки для игнорирования.
  11. Поместите свои файлы на физический диск, отличный от операционной системы и файла подкачки. Использование отдельного физического диска позволяет Windows использовать параллельные операции ввода-вывода для обоих дисков.
  12. Посмотрите на флаги вашего компилятора. Компилятор Windows C ++ имеет множество опций; убедитесь, что вы используете только те, которые вам действительно нужны.
  13. Попробуйте увеличить объем памяти, используемой ОС для буферов в выгружаемом пуле (сначала убедитесь, что у вас достаточно ОЗУ): fsutil behavior set memoryusage 2
  14. Проверьте журнал ошибок Windows, чтобы убедиться в отсутствии случайных ошибок на диске.
  15. Посмотрите на счетчики производительности, связанные с физическим диском, чтобы увидеть, насколько заняты ваши диски. Большая длина очереди или длительное время на передачу - плохие признаки.
  16. Первые 30% дисковых разделов намного быстрее, чем остальная часть диска с точки зрения времени сырой передачи. Более узкие разделы также помогают минимизировать время поиска.
  17. Используете ли вы RAID? Если это так, вам может потребоваться оптимизировать ваш выбор типа RAID (RAID-5 плохо подходит для таких операций записи, как компиляция)
  18. Отключите все ненужные вам службы
  19. Дефрагментация папок: копирование всех файлов на другой диск (только файлы), удаление исходных файлов, копирование всех папок на другой диск (только пустые папки), затем удаление оригинальных папок, дефрагментация исходного диска, копирование папки сначала верните структуру, затем скопируйте файлы. Когда Windows создает большие папки по одному файлу за раз, папки оказываются фрагментированными и медленными. (здесь также должно помочь "contig")
  20. Если вы связаны с вводом / выводом и у вас есть запасные циклы ЦП, попробуйте включить сжатие диска. Он может обеспечить значительное ускорение для файлов с высокой степенью сжатия (например, исходного кода), с некоторыми затратами на ЦП.
24 голосов
/ 20 декабря 2011

NTFS экономит время доступа к файлу каждый раз. Вы можете попробовать отключить его: "fsutil поведения установлен disablelastaccess 1" (Рестарт)

20 голосов
/ 19 декабря 2011

Проблема с Visual C ++, насколько я могу судить, заключается в том, что для команды компиляторов не является приоритетом оптимизация этого сценария.Их решение заключается в том, что вы используете их предварительно скомпилированную функцию заголовка.Это то, что сделали конкретные проекты Windows.Это не портативный, но работает.

Кроме того, в Windows обычно есть антивирусные сканеры, а также инструменты восстановления системы и поиска, которые могут полностью испортить время сборки, если они будут следить за вашей папкой buid.Windows 7 Resouce Monitor может помочь вам определить это.У меня есть ответ здесь с некоторыми дополнительными советами по оптимизации времени сборки vc ++, если вы действительно заинтересованы.

17 голосов
/ 19 декабря 2011

Лично я обнаружил, что при запуске виртуальной машины Windows в Linux удалось устранить большую часть медлительности ввода-вывода в Windows, вероятно потому, что linux vm выполнял много операций кэширования, чем сама Windows.

Делая этоМне удалось ускорить время компиляции большого (250Kloc) C ++ проекта, над которым я работал, примерно с 15 минут до 6 минут.

15 голосов
/ 19 декабря 2011

Сложность в этом заключается из-за того, что C ++ имеет тенденцию распространяться и сам процесс компиляции по многим маленьким, отдельным файлам. В Linux это хорошо, а в Windows нет. Если вы хотите создать действительно быстрый компилятор C ++ для Windows, постарайтесь сохранить все в оперативной памяти и как можно меньше касаться файловой системы.

Таким же образом вы создадите более быструю цепочку компиляции Linux C ++, но это менее важно в Linux, потому что файловая система уже выполняет большую часть этой настройки для вас.

Причина этого кроется в культуре Unix: Исторически производительность файловой системы была гораздо более приоритетной в мире Unix, чем в Windows. Нельзя сказать, что в Windows это не было приоритетом, просто в Unix это был более высокий приоритет.

  1. Доступ к исходному коду.

    Вы не можете изменить то, что не можете контролировать. Отсутствие доступа к исходному коду Windows NTFS означает, что большинство усилий по повышению производительности были сделаны с помощью аппаратных улучшений. То есть, если производительность низкая, вы решаете проблему, улучшая аппаратное обеспечение: шину, носитель данных и т. Д. Вы можете сделать так много, только если вам нужно обойти проблему, но не решить ее.

    Доступ к исходному коду Unix (даже до открытого кода) был более распространенным. Поэтому, если вы хотите повысить производительность, вы должны сначала обратиться к ней с помощью программного обеспечения (дешевле и проще), а затем с аппаратным обеспечением.

    В результате многие люди в мире получили докторскую степень, изучая файловую систему Unix и находя новые способы повышения производительности.

  2. Unix стремится к множеству маленьких файлов; Windows стремится к нескольким (или одному) большому файлу.

    Приложения Unix, как правило, имеют дело со многими небольшими файлами. Подумайте о среде разработки программного обеспечения: множество небольших исходных файлов, каждый со своей целью. На последнем этапе (связывание) создается один большой файл, но это небольшой процент.

    В результате Unix имеет высоко оптимизированные системные вызовы для открытия и закрытия файлов, сканирования каталогов и так далее. История научных исследований Unix охватывает десятилетия оптимизаций файловой системы, в которых много внимания уделялось улучшению доступа к каталогам (поиск и полное сканирование каталогов), открытию начальных файлов и т. Д.

    Приложения Windows, как правило, открывают один большой файл, держат его открытым в течение длительного времени, когда его закрывают, закрывают. Подумайте о MS-Word. msword.exe (или что-то еще) открывает файл один раз и добавляет в течение нескольких часов, обновляет внутренние блоки и так далее. Значение оптимизации открытия файла будет потрачено впустую время.

    История тестирования и оптимизации Windows была связана с тем, насколько быстро можно читать или записывать длинные файлы. Вот что оптимизируется.

    К сожалению, разработка программного обеспечения имеет тенденцию к первой ситуации. Черт возьми, лучшая система обработки текста для Unix (TeX / LaTeX) предлагает вам поместить каждую главу в отдельный файл и #include их все вместе.

  3. Unix ориентирован на высокую производительность; Windows ориентирована на пользовательский опыт

    Unix запущен в серверной комнате: пользовательский интерфейс отсутствует. Единственное, что видят пользователи, это скорость. Поэтому скорость является приоритетом.

    Windows запустилась на рабочем столе: пользователи заботятся только о том, что они видят, и они видят пользовательский интерфейс. Поэтому на улучшение пользовательского интерфейса тратится больше энергии, чем на производительность.

  4. Экосистема Windows зависит от планового устаревания. Зачем оптимизировать программное обеспечение, если до нового оборудования всего год или два?

    Я не верю в теории заговора, но если бы я это сделал, я бы отметил, что в культуре Windows меньше стимулов для повышения производительности.Бизнес-модели Windows зависят от людей, покупающих новые машины, такие как часы.(Вот почему цена акций тысяч компаний будет затронута, если MS поставит операционную систему с опозданием или Intel пропустит дату выпуска чипа.)Это означает, что есть стимул решать проблемы с производительностью, говоря людям покупать новое оборудование;не путем улучшения реальной проблемы: медленные операционные системы.Unix происходит из научных кругов, где бюджет ограничен, и вы можете получить докторскую степень, придумав новый способ сделать файловые системы быстрее;редко кто-то в академии получает очки за решение проблемы путем выдачи заказа на покупку.В Windows не существует заговора с целью замедления работы программного обеспечения, но вся экосистема зависит от запланированного устаревания.

    Кроме того, поскольку Unix является открытым исходным кодом (даже если его не было, у всех был доступ к источнику), любой скучающий доктор наукстудент может прочитать код и стать известным, сделав его лучше.Этого не происходит в Windows (у MS есть программа, которая предоставляет ученым доступ к исходному коду Windows, им редко пользуются).Посмотрите на этот список работ, связанных с Unix: http://www.eecs.harvard.edu/margo/papers/ или посмотрите историю работ Остерхауса, Генри Спенсера или других.Черт возьми, одним из самых больших (и наиболее приятных для просмотра) дебатов в истории Unix были споры между Остерхаусом и Селцером http://www.eecs.harvard.edu/margo/papers/usenix95-lfs/supplement/rebuttal.html В мире Windows такого не происходит.Вы можете видеть, как поставщики сталкиваются друг с другом, но в последнее время это кажется гораздо более редким явлением, поскольку кажется, что все инновации находятся на уровне стандартов.

Вот как я это вижу.

Обновление: Если вы посмотрите на новые цепочки компиляторов, которые выходят из Microsoft, вы будете очень оптимистичны, потому что большая часть того, что они делают, облегчает сохранение всего набора инструментовв оперативной памяти и повторять меньше работы.Очень впечатляющий материал.

7 голосов
/ 02 августа 2011

Инкрементное связывание

Если решение VC 2008 настроено как несколько проектов с выходами .lib, необходимо установить «Использовать входы зависимостей библиотеки»; это делает ссылку компоновщиком непосредственно на файлы .obj, а не на .lib. (И фактически делает это постепенно ссылкой.)

Производительность обхода каталога

Немного несправедливо сравнивать обход каталога на исходном компьютере с обходом недавно созданного каталога с теми же файлами на другом компьютере. Если вам нужен эквивалентный тест, вам, вероятно, следует сделать еще одну копию каталога на исходном компьютере. (Это все еще может быть медленным, но это может быть связано с любым количеством вещей: фрагментация диска, короткие имена файлов, фоновые службы и т. Д.) Хотя я думаю, что проблемы с perf для dir /s больше связаны с записью вывода, измерение фактической производительности обхода файла. Даже dir /s /b > nul работает медленно на моей машине с огромным каталогом.

6 голосов
/ 19 декабря 2011

Я почти уверен, что это связано с файловой системой.Я работаю над кроссплатформенным проектом для Linux и Windows, где весь код является общим, за исключением тех случаев, когда платформозависимый код абсолютно необходим.Мы используем Mercurial, а не git, поэтому «Linuxness» git не применяется.Внесение изменений из центрального репозитория в Windows занимает вечно по сравнению с Linux, но я должен сказать, что наши машины с Windows 7 работают намного лучше, чем машины с Windows XP.Компиляция кода после этого еще хуже на VS 2008. Это не просто hg;CMake работает намного медленнее и в Windows, и оба эти инструмента используют файловую систему больше, чем что-либо еще.

Проблема настолько серьезна, что большинство наших разработчиков, работающих в среде Windows, даже небольше не надо делать инкрементные сборки - они обнаруживают, что делает сборку единства вместо быстрее.

Кстати, если вы хотите значительно увеличить скорость компиляции в Windows, я бы предложил вышеупомянутую сборку единства,Правильно реализовать это в системе сборки (я сделал это для нашей команды в CMake), но однажды все сделано автоматически, что ускоряет работу наших серверов непрерывной интеграции.В зависимости от того, сколько двоичных файлов выдает ваша система сборки, вы можете получить от 1 до 2 порядков улучшения.Ваш пробег может варьироваться.В нашем случае я думаю, что он ускорил сборку Linux в три раза, а сборку Windows - примерно в 10 раз, но у нас есть много общих библиотек и исполняемых файлов (что уменьшает преимущества единой сборки).

5 голосов
/ 02 марта 2012

Как вы строите свой большой кроссплатформенный проект?Если вы используете общие make-файлы для Linux и Windows, вы можете легко снизить производительность Windows в 10 раз, если make-файлы не предназначены для быстрой работы в Windows.

Я только что исправил некоторые make-файлы кроссплатформенного проекта, используяобщие (GNU) make-файлы для Linux и Windows.Make запускает процесс sh.exe для каждой строки рецепта, вызывая разницу в производительности между Windows и Linux!

В соответствии с документацией GNU make

.ONESHELL:

должен решить проблему, но эта функция (в настоящее время) не поддерживается для Windows make.Поэтому переписывание рецептов в одну логическую строку (например, путем добавления; \ или \ в конце текущих строк редактора) сработало очень хорошо!

4 голосов
/ 22 декабря 2011

ИМХО, это все о производительности дискового ввода-вывода.Порядок величины предполагает, что многие операции выполняются на диске под Windows, тогда как в Linux они обрабатываются в памяти, то есть Linux лучше кешируется.Лучшим вариантом под Windows будет переместить ваши файлы на быстрый диск, сервер или файловую систему.Подумайте о покупке твердотельного диска или о перемещении файлов на виртуальный диск или быстрый NFS-сервер.

Я выполнил тесты обхода каталога, и результаты очень близки к отчетному времени компиляции, что говорит о том, что это не имеет никакого отношения ко времени обработки ЦП или алгоритмам компилятора / компоновщика.

Измеренное времякак было предложено выше, обход дерева каталогов хрома:

  • Windows Home Premium 7 (8 ГБ ОЗУ) в NTFS: 32 секунды
  • Ubuntu 11.04 Linux (2 ГБ ОЗУ) в NTFS: 10 секунд
  • Ubuntu 11.04 Linux (2 ГБ ОЗУ) на ext4: 0,6 секунды

Для тестов я вытащил источники хрома (оба под win / linux)

git clone http://github.com/chromium/chromium.git 
cd chromium
git checkout remotes/origin/trunk 

Чтобы измерить время, которое я запустил

ls -lR > ../list.txt ; time ls -lR > ../list.txt # bash
dir -Recurse > ../list.txt ; (measure-command { dir -Recurse > ../list.txt }).TotalSeconds  #Powershell

, я отключил метки времени доступа, мой антивирусный сканер и увеличил настройки диспетчера кэша в Windows (> 2 ГБ ОЗУ) - и все это без каких-либо заметных улучшений.Дело в том, что из коробки Linux работала в 50 раз лучше, чем Windows с четвертью оперативной памяти.

Для всех, кто хочет утверждать, что цифры неправильные - по любой причине - пожалуйста, попробуйте и опубликуйте свои выводы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...