Mac 152
=======

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

 в настоящее время у вас есть такие вещи, как Native POSIX Thread Library - если хотите. Но долгое время единственным способом «делегировать» работу в мире Unix было использование fork () (и это все еще предпочитается во многих, многих обстоятельствах). например какой-то сокет сервер

```
socket\_accept()
fork()
if (child)
    handleRequest()
else
    goOnBeingParent()

```
Поэтому реализация fork должна быть быстрой, и с течением времени было реализовано много оптимизаций. Microsoft одобрила CreateThread или даже волокна вместо создания новых процессов и использования межпроцессного взаимодействия. Я думаю, что не совсем справедливо сравнивать CreateProcess с fork, поскольку они не являются взаимозаменяемыми. Вероятно, более уместно сравнить fork / exec с CreateProcess.

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

Роб, это правда, что форк относительно дешев, когда используется COW, но на самом деле за форком в большинстве случаев следует exec. И исполнительный директор должен также загрузить все изображения. Обсуждение производительности форка, следовательно, является лишь частью правды.

При обсуждении скорости создания процесса, вероятно, будет хорошей идеей провести различие между NT и Windows / Win32. Что касается NT (то есть самого ядра), я не думаю, что создание процессов (NtCreateProcess) и создание потоков (NtCreateThread) значительно медленнее, чем в среднем в Unix. Возможно, будет происходить немного больше, но я не вижу основной причины разницы в производительности здесь.

Однако, если вы посмотрите на Win32, вы заметите, что он добавляет много накладных расходов на создание процесса. Во-первых, он требует, чтобы CSRSS был уведомлен о создании процесса, который включает в себя LPC. Для этого требуется как минимум ядро 32 для дополнительной загрузки, и он должен выполнить ряд дополнительных рабочих операций бухгалтерии, прежде чем процесс будет считаться полноценным процессом Win32. И давайте не будем забывать обо всех дополнительных накладных расходах, возникающих при разборе манифестов, проверке, требует ли образ прокладку совместимости, проверке, применяются ли политики ограниченного использования программ, yada yada.

Тем не менее, я вижу общее замедление в сумме всех тех мелочей, которые нужно сделать в дополнение к необработанному созданию процесса, пространства виртуальных машин и исходного потока. Но, как было сказано в начале - из-за предпочтения многопоточности по сравнению с многозадачностью, единственное программное обеспечение, которое серьезно затронуто этими дополнительными затратами, - это плохо портированное программное обеспечение Unix. Хотя эта ситуация меняется, когда такие программы, как Chrome и IE8, неожиданно открывают преимущества многопроцессорной обработки и начинают часто запускать и завершать процессы ...



Краткий ответ - «программные слои и компоненты».нтов, которых нет в Unix или которые упрощены и обрабатываются внутри ядра в Unix.

В Unix fork и exec являются прямыми вызовами ядра.

В Windows API ядра не используется напрямую, поверх него есть win32 и некоторые другие компоненты, поэтому создание процесса должно проходить через дополнительные слои, а затем новый процесс должен запускаться или подключаться к этим слоям и компонентам.

В течение достаточно долгого времени исследователи и корпорации пытались смутно подобрать Unix, обычно основывая свои эксперименты на[Ядро маха](https://en.wikipedia.org/wiki/Mach_kernel); хорошо известный пример[OS X.](https://en.wikipedia.org/wiki/Mac_OS_X), Однако каждый раз, когда они пытаются это сделать, они становятся настолько медленными, что в конечном итоге они, по крайней мере, частично объединяют части обратно в ядро либо навсегда, либо для производственных поставок.



 по-видимому, есть какое-то оправдание MS-Windows, например,

«Ядро NT и Win32 - это не одно и то же. Если вы программируете на ядро NT, это не так уж и плохо »- правда, но если вы не пишете подсистему Posix, то кого это волнует? Вы будете писать в win32.«Несправедливо сравнивать форк, с ProcessCreate, поскольку они делают разные вещи, а в Windows нет форка» - правда, поэтому я буду сравнивать подобное с лайком. Однако я также буду сравнивать fork, потому что он имеет много вариантов использования, таких как изоляция процесса (например, каждая вкладка веб-браузера работает в отдельном процессе).Теперь давайте посмотрим на факты, в чем разница в производительности?Данные зарезервированы от<http://www.bitsnbites.eu/benchmarking-os-primitives/>.  
Поскольку смещение неизбежно, при обобщении я сделал это в пользу MS-Windows  
Аппаратное обеспечение для большинства тестов i7 8 core 3,2 ГГц. За исключением Raspberry-Pi под управлением Gnu / Linux

В порядке скорости, от самой быстрой до самой медленной (числа - время, меньше - лучше).

Linux CreateThread 12Mac CreateThread 15Linux Fork 19Windows CreateThread 25Linux CreateProcess (форк + exec) 45Mac Fork 105Mac CreateProcess (форк + exec) 453Raspberry-Pi CreateProcess (форк + exec) 501Windows CreateProcess 787Windows CreateProcess с антивирусным сканером 2850Windows Fork (симуляция с помощью CreateProcess + fixup) больше 2850Примечания: на Linux`fork` быстрее, чем MS-Windows предпочитал метод CreateThread.

Теперь о некоторых других фигурахСоздание файла.Linux 13Mac 113Windows 225Raspberry-Pi (с медленной SD-картой) 241Windows с защитником, антивирусом и т. Д. 12950Выделение памятиLinux 79Windows 93Mac 152

Я думаю, что люди могли бы извлечь выгоду из чтения "Showstopper"; книга о разработке Windows NT.

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

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

На Unices (в общем) сегменты кода общих библиотек (DLL) фактически являются общими.

Windows NT загружает копию библиотеки DLL для каждого процесса, поскольку после загрузки она манипулирует сегментом кода библиотеки (и сегментом исполняемого кода). (Сообщает, где ваши данные?)

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

Таким образом, процесс создания NT на самом деле довольно дорогой. С другой стороны, это делает DLL не заметной экономией в памяти, а шансом проблем с зависимостями между приложениями.

Иногда в инженерном деле стоит отступить назад и сказать: «Теперь, если бы мы собирались спроектировать это так, чтобы он действительно отстой, как бы это выглядело?»

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



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

Unix-системы изначально были многопользовательскими системами и серверами. Особенно для последних весьма часто иметь процессы (например, mail или http-демоны), которые разделяют процессы для обработки определенных заданий (например, заботятся об одном входящем соединении). Важным фактором в этом является дешевый`fork` метод (который, как упоминал Роб Уокер ([47865](https://stackoverflow.com/questions/47845/why-is-creating-a-new-process-more-expensive-on-windows-than-linux#47865)), изначально использует ту же память для вновь созданного процесса), что очень полезно, поскольку новый процесс сразу же получает всю необходимую ему информацию.

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

Отказ от ответственности: я ни в коем случае не эксперт в этом вопросе, так что прости меня, если я ошибся.



 что модель безопасности в Windows значительно сложнее, чем в Unix-системах, что добавляет много накладных расходов при создании процессов. Еще одна причина, по которой многопоточность предпочтительнее многопроцессорности в Windows.



 что на машине Win, скорее всего, антивирусное программное обеспечение сработает во время CreateProcess ... Это обычно самое большое замедление.



 большая часть накладных расходов принадлежит запуску Win32 для процесса.

Ядро Windows NT на самом деле поддерживает форк COW.[СФУ](https://technet.microsoft.com/en-us/interopmigration/bb380242.aspx) (Среда Microsoft UNIX для Windows) использует их. Тем не менее, Win32 не поддерживает форк. Процессы SFU не являются процессами Win32. SFU ортогонален Win32: они обе подсистемы среды, построенные на одном ядре.

В дополнение к внепроцессным вызовам LPC`CSRSS`, в XP и более поздних версиях существует внепроцессный вызов механизма совместимости приложений, чтобы найти программу в базе данных совместимости приложений. Этот шаг вызывает достаточные накладные расходы, что Microsoft предоставляет возможность групповой политики для[отключить движок совместимости на WS2003](https://technet.microsoft.com/en-us/library/cc784527.aspx) по причинам производительности.

Библиотеки времени выполнения Win32 (kernel32.dll и т. Д.) Также выполняют много операций чтения и инициализации реестра при запуске, которые не применяются к UNIX, SFU или собственным процессам.

Собственные процессы (без подсистемы среды) создаются очень быстро. SFU делает намного меньше, чем Win32 для создания процессов, поэтому его процессы также быстро создаются.

ОБНОВЛЕНИЕ ДЛЯ 2019: добавьте LXSS:[Подсистема Windows для Linux](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#Architecture)

Замена SFU для Windows 10 - это подсистема среды LXSS. Это 100% режим ядра и не требует никакого IPC, который Win32 продолжает использовать. Системный вызов для этих процессов направляется непосредственно в lxss.sys / lxcore.sys, поэтому вызов fork () или другого процесса, создающего вызов, стоит всего 1 системного вызова для создателя, всего.[[Область данных, называемая экземпляром] отслеживает все процессы LX, потоки и состояние времени выполнения.](https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/)

Процессы LXSS основаны на собственных процессах, а не на процессах Win32. Все специфичные для Win32 вещи, такие как механизм совместимости, вообще не задействованы.



fork', который 'разделяет' текущий процесс на два и дает вам второй процесс, идентичный первому (по модулю возврата из вызова fork). Поскольку адресное пространство нового процесса уже запущено и работает, это должно быть дешевле, чем вызывать «CreateProcess» в Windows и загружать образ exe, связанные библиотеки и т. Д.

В случае ветвления ОС может использовать семантику «копирование при записи» для страниц памяти, связанных с обоими новыми процессами, чтобы гарантировать, что каждый получит свою собственную копию страниц, которые они впоследствии изменят.