Как заставить Windows идти так же быстро, как Linux для компиляции С++?

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

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

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

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

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

Как простой тест, найдите папку с большим количеством подпапок и выполните простой

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 секунда.

Есть ли параметр реестра, который я могу настроить для ускорения работы Windows? Что дает?


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

Ответ 1

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

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

  • Кэширование

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

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

Ответ 2

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

  • Отключить имена 8.3. Это может быть большим фактором для дисков с большим количеством файлов и относительно небольшим количеством папок: fsutil behavior set disable8dot3 1
  • Используйте больше папок. По моему опыту, NTFS начинает замедляться с более чем 1000 файлами в папке.
  • Включить параллельные сборки с помощью MSBuild; просто добавьте переключатель "/m", и он автоматически запустит одну копию MSBuild на ядро ​​процессора.
  • Поместите ваши файлы на SSD - очень помогает для случайного ввода-вывода.
  • Если ваш средний размер файла намного больше 4 КБ, подумайте о перестройке файловой системы с большим размером кластера, который примерно соответствует среднему размеру файла.
  • Убедитесь, что файлы были дефрагментированы. Фрагментированные файлы вызывают множество обращений к дискам, которые могут стоить вам 40% в пропускной способности. Используйте утилиту "contig" из sysinternals или встроенного дефрагментатора Windows.
  • Если ваш средний размер файла невелик, а раздел, на котором вы находитесь, является относительно полным, возможно, что вы работаете с фрагментированным MFT, что плохо для производительности. Кроме того, файлы размером менее 1K хранятся непосредственно в MFT. Упомянутая выше утилита "contig" может помочь, или вам может потребоваться увеличить размер MFT. Следующая команда удвоит его, до 25% от объема: fsutil behavior set mftzone 2 Измените последнее число на 3 или 4, чтобы увеличить размер с шагом 12,5%. После запуска команды перезагрузитесь, а затем создайте файловую систему.
  • Отключить последнее время доступа: fsutil behavior set disablelastaccess 1
  • Отключить службу индексирования
  • Отключите антивирусное и антишпионское программное обеспечение или по крайней мере установите соответствующие папки для игнорирования.
  • Поместите ваши файлы на другой физический диск из ОС и файла подкачки. Использование отдельного физического диска позволяет Windows использовать параллельные входы/выходы для обоих дисков.
  • Посмотрите на свои флагов компилятора. Компилятор Windows С++ имеет массу опций; убедитесь, что вы используете только те, которые вам действительно нужны.
  • Попробуйте увеличить объем памяти, используемой ОС для буферов выгружаемого пула (сначала убедитесь, что у вас достаточно ОЗУ): fsutil behavior set memoryusage 2
  • Проверьте журнал ошибок Windows, чтобы убедиться, что вы не испытываете случайных ошибок на диске.
  • Посмотрите на счетчики производительности, связанные с физическим диском, чтобы узнать, насколько заняты ваши диски. Высокие длины очереди или длинные периоды на перенос - это плохие признаки.
  • Первые 30% дисковых разделов намного быстрее, чем остальная часть диска с точки зрения необработанного времени передачи. Более узкие разделы также помогают минимизировать время поиска.
  • Вы используете RAID? Если это так, вам может потребоваться оптимизировать ваш выбор типа RAID (RAID-5 плохо для операций с записью, таких как компиляция)
  • Отключить любые службы, которые вам не нужны.
  • Дефрагментация папок: скопируйте все файлы на другой диск (только файлы), удалите исходные файлы, скопируйте все папки на другой диск (только пустые папки), затем удалите исходные папки, дефрагментируйте исходный диск, скопируйте папку сначала создайте структуру, затем скопируйте файлы. Когда Windows строит большие папки по одному файлу за раз, папки становятся фрагментированными и медленными. ( "contig" также должен помочь здесь)
  • Если вы привязаны к вводу/выводу и имеете запасные циклы CPU, попробуйте включить сжатие диска. Он может обеспечить некоторые значительные ускорения для сильно сжимаемых файлов (например, исходного кода), с некоторой стоимостью в ЦП.

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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

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

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

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

  • Unix имеет тенденцию ко многим небольшим файлам; Windows имеет тенденцию к нескольким (или одному) большому файлу.

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

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

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

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

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

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

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

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

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

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

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

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

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

Ответ 7

Инкрементальная привязка

Если решение VC 2008 настроено как несколько проектов с выводами .lib, вам нужно установить "Использовать вкладки зависимостей библиотеки"; это делает линкер прямо ссылкой на файлы .obj, а не на .lib. (И на самом деле делает его пошагово.)

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

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

Ответ 8

Я уверен, что это связано с файловой системой. Я работаю над кросс-платформенным проектом для 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 раз, но у нас есть много разделяемых библиотек и исполняемых файлов (что уменьшает преимущества сборки единства).

Ответ 9

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

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

Согласно документации GNU make

.ONESHELL:

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

Ответ 10

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

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

Измеренные времена, как указано выше, пересекают дерево каталогов хрома:

  • Windows Home Premium 7 (8GB Ram) на NTFS: 32 секунды
  • Ubuntu 11.04 Linux (2GB Ram) на NTFS: 10 секунд
  • Ubuntu 11.04 Linux (2GB Ram) на 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

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

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

Ответ 11

Попробуйте использовать jom вместо nmake

Получите его здесь: http://qt.gitorious.org/qt-labs/jom

Дело в том, что nmake использует только один из ваших ядер, jom - это клон nmake, который использует многоядерные процессоры.

GNU делает это из-за коробки благодаря опции -j, что может быть причиной его скорости по сравнению с Microsoft nmake.

jom работает, выполняя параллельно различные команды make на разных процессорах/ядрах. Попробуйте сами почувствовать разницу!

Ответ 12

Я хочу добавить только одно наблюдение с помощью Gnu make и других инструментов из инструментов MinGW в Windows: они, похоже, разрешают имена хостов, даже когда инструменты не могут даже общаться через IP. Я предполагаю, что это вызвано некоторой процедурой инициализации среды выполнения MinGW. Запуск локального прокси-сервера DNS помог мне улучшить скорость компиляции с помощью этих инструментов.

До того, как я получил большую головную боль, потому что скорость сборки снизилась примерно в 10 раз, когда я параллельно открывал VPN-соединение. В этом случае все эти DNS-запросы прошли через VPN.

Это наблюдение может также применяться к другим инструментам сборки, а не только к MinGW, и в то же время оно могло быть изменено на последней версии MinGW.

Ответ 13

Недавно я мог архивировать другой способ ускорить компиляцию примерно на 10% в Windows, используя Gnu make, заменив mingw bash.exe на версию из win-bash