Почему создание нового процесса более дорогостоящим в Windows, чем Linux?

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

Ответ 1

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

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

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

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

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

Ответ 2

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

В случае fork ОС может использовать семантику "copy-on-write" для страниц памяти, связанных с обоими новыми процессами, чтобы гарантировать, что каждая из них получит свою собственную копию страниц, которые они впоследствии изменяют.

Ответ 3

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

Ядро Windows NT на самом деле поддерживает форк COW. SFU (среда Microsoft UNIX для Windows) использует их. Тем не менее, Win32 не поддерживает форк. Процессы SFU не являются процессами Win32. SFU ортогонален Win32: они обе подсистемы среды, построенные на одном и том же ядре.

В дополнение к внепроцессным вызовам LPC в CSRSS, в XP и более поздних версиях существует CSRSS вызов механизма совместимости приложений для поиска программы в базе данных совместимости приложений. Этот шаг вызывает достаточные накладные расходы, поэтому Microsoft предоставляет возможность групповой политики отключить механизм совместимости на WS2003 по соображениям производительности.

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

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

ОБНОВЛЕНИЕ ДЛЯ 2019: добавьте LXSS: Подсистема Windows для Linux

Замена SFU для Windows 10 - это подсистема среды LXSS. Это 100% режим ядра и не требует никакого IPC, который Win32 продолжает использовать. Системный вызов для этих процессов направляется непосредственно в lxss.sys/lxcore.sys, поэтому вызов fork() или другого процесса, создающего вызов, стоит всего 1 системный вызов для создателя, всего. [Область данных, называемая экземпляром] отслеживает все процессы LX, потоки и состояние времени выполнения.

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

Ответ 4

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

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

Ответ 5

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

Системы на основе Unix изначально были многопользовательскими системами и серверами. Особенно для последних нередко возникают процессы (например, почтовые или http-демоны), которые отделяют процессы для обработки определенных заданий (например, заботятся о одном входящем соединении). Важным фактором в этом является дешевый метод fork (который, как упоминал Роб Уокер (47865), изначально использует ту же самую память для вновь созданного процесс), который очень полезен, поскольку новый процесс немедленно имеет всю необходимую ему информацию.

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

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

Ответ 6

Короткий ответ - "программные уровни и компоненты".

Архитектура Windows SW имеет несколько дополнительных уровней и компонентов, которые не существуют в Unix или упрощены и обработаны внутри ядра в Unix.

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

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

В течение некоторого времени исследователи и корпорации пытались разбить Unix смутно подобным образом, как правило, основывая свои эксперименты на Mach kernel; хорошо известный пример OS X.. Каждый раз, когда они пытаются, тем не менее, он становится настолько медленным, что они, по крайней мере, частично сливают части обратно в ядро ​​либо навсегда, либо на производственные поставки.

Ответ 7

Ну, похоже, существует много способов "это лучше".

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

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

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

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

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

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

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

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

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

Ответ 8

Поскольку в некоторых ответах, кажется, есть какое-то оправдание MS-Windows, например

  • "Ядро NT и Win32 - это не одно и то же. Если вы программируете на ядро NT, это не так уж плохо" - правда, но если вы не пишете подсистему Posix, то кого это волнует? Вы будете писать в win32.
  • "Несправедливо сравнивать fork с ProcessCreate, поскольку они делают разные вещи, а в Windows нет fork" - правда, поэтому я буду сравнивать подобное с подобным. Однако я также буду сравнивать fork, поскольку он имеет много вариантов использования, таких как изоляция процессов (например, каждая вкладка веб-браузера работает в отдельном процессе).

Теперь давайте посмотрим на факты, в чем разница в производительности?

Данные подготовлены с сайта http://www.bitsnbites.eu/benchmarking-os-primitives/.
Поскольку смещение неизбежно, при обобщении я сделал это в пользу MS-Windows
Аппаратное обеспечение для большинства тестов i7 8 core 3,2 ГГц. За исключением Raspberry-Pi под управлением Gnu/Linux

A comparison of various basic operations, on Gnu/Linux, Apple-Mac, and Microsoft's Windows (smaller is better)

A comparison of MS-Windows process create vs Linux

Примечания: В Linux, fork быстрее, чем MS-Window предпочитал метод CreateThread.

Числа для операций типа создания процесса (потому что трудно увидеть значение для Linux на диаграмме).

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

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

Числа для других измерений

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

Ответ 9

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

Ответ 10

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