为什么在 Windows 上创建新进程比在 Linux 上更昂贵?

2024-10-22 08:29:00
admin
原创
70
摘要:问题描述:我听说在 Windows 机器上创建新进程的成本比在 Linux 上更高。这是真的吗?有人能解释一下为什么成本更高,以及提供这些原因背后的设计决策的历史原因吗?解决方案 1:mweerden:NT 从第一天起就被设计为多用户,所以这不是真正的原因。但是,您说得对,进程创建在 NT 上的作用不如在 U...

问题描述:

我听说在 Windows 机器上创建新进程的成本比在 Linux 上更高。这是真的吗?有人能解释一下为什么成本更高,以及提供这些原因背后的设计决策的历史原因吗?


解决方案 1:

mweerden:NT 从第一天起就被设计为多用户,所以这不是真正的原因。但是,您说得对,进程创建在 NT 上的作用不如在 Unix 上重要,因为与 Unix 相比,NT 更倾向于多线程而不是多处理。

Rob,确实,使用 COW 时 fork 相对便宜,但事实上,fork 之后大多会执行 exec。而且 exec 还必须加载所有图像。因此,讨论 fork 的性能只是事实的一部分。

在讨论进程创建速度时,区分 NT 和 Windows/Win32 可能是一个好主意。就 NT(即内核本身)而言,我认为进程创建(NtCreateProcess)和线程创建(NtCreateThread)的速度不会比普通 Unix 慢很多。可能还存在一些其他问题,但我看不出这里性能差异的主要原因。

但是,如果您查看 Win32,就会发现它为进程创建增加了相当多的开销。首先,它要求将进程创建通知给 CSRSS,这涉及 LPC。它至少需要额外加载 kernel32,并且必须执行许多额外的簿记工作项目,然后才能将进程视为成熟的 Win32 进程。我们不要忘记解析清单、检查映像是否需要兼容性垫片、检查软件限制策略是否适用等所有额外开销。

话虽如此,我看到除了创建进程、VA 空间和初始线程之外,所有这些小事情的总和都会导致整体速度减慢。但正如开头所说——由于人们更倾向于多线程而不是多任务,唯一受到这种额外开销严重影响的软件是移植不良的 Unix 软件。尽管当 Chrome 和 IE8 等软件突然重新发现多处理的好处并开始频繁启动和拆除进程时,这种情况发生了变化……

解决方案 2:

补充一下 JP 所说的:大部分开销属于该过程的 Win32 启动。

Windows NT 内核实际上支持 COW fork。SFU ( Microsoft 的 Windows UNIX 环境)使用它们。但是,Win32 不支持 fork。SFU 进程不是 Win32 进程。SFU 与 Win32 正交:它们都是基于同一内核构建的环境子系统。

除了对 的进程外 LPC 调用之外CSRSS,在 XP 及更高版本中,还会对应用程序兼容性引擎进行进程外调用,以在应用程序兼容性数据库中查找程序。此步骤会造成足够的开销,因此 Microsoft 提供了一个组策略选项来禁用 WS2003 上的兼容性引擎,以达到性能目的。

Win32 运行时库(kernel32.dll 等)在启动时也会执行大量注册表读取和初始化操作,这些操作不适用于 UNIX、SFU 或本机进程。

本机进程(没有环境子系统)创建速度非常快。SFU 在进程创建方面所做的工作比 Win32 少很多,因此其进程创建速度也很快。

2019 年更新:添加 LXSS:适用于 Linux 的 Windows 子系统

取代 Windows 10 的 SFU 的是 LXSS 环境子系统。它是 100% 内核模式,不需要 Win32 继续拥有的任何 IPC。这些进程的系统调用直接指向 lxss.sys/lxcore.sys,因此 fork() 或其他进程创建调用总共只需要创建者进行 1 次系统调用。[称为实例的数据区域] 跟踪所有 LX 进程、线程和运行时状态。

LXSS 进程基于本机进程,而不是 Win32 进程。所有 Win32 特有的东西(例如兼容引擎)都完全没有参与。

解决方案 3:

Unix 有一个“fork”系统调用,它将当前进程“拆分”为两个,并为您提供与第一个进程相同的第二个进程(对 fork 调用的返回值取模)。由于新进程的地址空间已经启动并运行,因此这应该比在 Windows 中调用“CreateProcess”并让其加载 exe 映像、相关 dll 等更便宜。

在 fork 情况下,操作系统可以对与两个新进程相关的内存页面使用“写时复制”语义,以确保每个进程都获得随后修改的页面的副本。

解决方案 4:

除了 Rob Walker 的回答之外:现在,如果您愿意,您可以使用 Native POSIX 线程库之类的东西。但长期以来,在 unix 世界中“委托”工作的唯一方法是使用 fork()(在很多情况下,它仍然是首选)。例如某种套接字服务器

socket_accept()
叉()
如果(子项)
    处理请求()
别的
    转到父类()

因此,fork 的实现必须快速,并且随着时间的推移,已经实现了许多优化。Microsoft 认可 CreateThread 甚至纤程,而不是创建新进程和使用进程间通信。我认为将 CreateProcess 与 fork 进行比较并不“公平”,因为它们不可互换。将 fork/exec 与 CreateProcess 进行比较可能更合适。

解决方案 5:

我认为,这个问题的关键在于这两个系统的历史用法。Windows(以及之前的 DOS)最初是个人电脑的单用户系统。因此,这些系统通常不必一直创建大量进程;(非常)简单地说,只有当这个孤独的用户请求时才会创建一个进程(相对而言,我们人类的操作速度不是很快)。

基于 Unix 的系统最初是多用户系统和服务器。特别是对于后者,将进程(例如邮件或 http 守护进程)拆分成处理特定任务(例如处理一个传入连接)的情况并不少见。这样做的一个重要因素是廉价的方法(如 Rob Walker ( 47865fork )所述,该方法最初为新创建的进程使用相同的内存),这非常有用,因为新进程可以立即获得所需的所有信息。

显然,至少从历史上看,基于 Unix 的系统对快速进程创建的需求远高于 Windows 系统。我认为现在情​​况仍然如此,因为基于 Unix 的系统仍然非常面向进程,而 Windows 则由于其历史原因可能更加面向线程(线程对于制作响应式应用程序非常有用)。

免责声明:我绝不是这个问题的专家,所以如果我错了,请原谅我。

解决方案 6:

简短的回答是“软件层和组件”。

Windows SW 架构有几个额外的层和组件,这些层和组件在 Unix 上不存在,或者在 Unix 的内核中被简化和处理。

在 Unix 上,fork 和 exec 是直接调用内核。

在 Windows 上,内核 API 并不直接使用,而是在它之上有 win32 和某些其他组件,因此进程创建必须经过额外的层,然后新进程必须启动或连接到这些层和组件。

很长一段时间以来,研究人员和公司都试图以类似的方式拆分 Unix,通常以Mach 内核为基础进行实验;一个著名的例子就是OS X。然而,每次他们尝试时,速度都非常慢,最终他们不得不至少部分地将各个部分永久合并回内核或用于生产发布。

解决方案 7:

呃,似乎有很多“这样更好”之类的理由。

我认为阅读《Showstopper》这本关于 Windows NT 开发的书会对人们有益。

在 Windows NT 上,服务作为 DLL 在同一个进程中运行的原因是,作为单独的进程运行它们太慢了。

如果你认真研究一下,你就会发现库加载策略是一个问题。

在 Unices 上(一般来说),共享库(DLL)代码段实际上是共享的。

Windows NT 每个进程都加载 DLL 的一个副本,因为它在加载后会操作库代码段(和可执行代码段)。(告诉它你的数据在哪里?)

这会导致库中的代码段不可重用。

因此,NT 进程创建实际上非常昂贵。而不利的一面是,它不会显著节省 DLL 的内存,反而有可能引发应用程序间依赖性问题。

在工程设计中,有时我们需要退后一步,然后思考:“现在,如果我们要设计一个非常糟糕的产品,它会是什么样子?”

我曾经使用过一个嵌入式系统,它曾经非常不稳定,有一天我查看它时意识到它是一个腔体磁控管,电子元件位于微波腔体中。之后我们让它变得更加稳定(不再像微波炉)。

解决方案 8:

因为有些答案似乎对 MS-Windows 有所解释,例如

  • “NT 内核和 Win32 不是一回事。如果你针对 NT 内核编程,那就没那么糟糕了”——没错,但除非你正在编写 Posix 子系统,否则谁会在乎呢。你将针对 win32 进行编写。

  • “将 fork 与 ProcessCreate 进行比较是不公平的,因为它们的作用不同,而且 Windows 没有 fork” — 是的,所以我会比较同类事物。但是我也会比较 fork,因为它有很多用例,例如进程隔离(例如,Web 浏览器的每个选项卡都在不同的进程中运行)。

现在我们来看看事实,性能上有什么区别?

数据摘自http://www.bitsnbites.eu/benchmarking-os-primitives/

由于偏见不可避免,总结时,我倾向于

在大多数测试中使用 MS-Windows 硬件 i7 8 核 3.2GHz。运行 Gnu/Linux 的 Raspberry-Pi 除外

Gnu/Linux、Apple-Mac 和 Microsoft Windows 上各种基本操作的比较(越小越好)

MS-Windows 进程创建与 Linux 的比较

注意:在 Linux 上,fork比 MS-Window 的首选方法更快CreateThread

进程创建类型操作的数字(因为在图表中很难看到 Linux 的值)。

按速度排序,从最快到最慢(数字是时间,越小越好)。

  • Linux 创建线程 12

  • Mac CreateThread 15

  • Linux Fork 19

  • Windows 创建线程 25

  • Linux CreateProcess(fork+exec) 45

  • 麦克福克 105

  • Mac CreateProcess(fork+exec) 453

  • Raspberry-Pi CreateProcess(fork + exec)501

  • Windows 创建进程 787

  • Windows CreateProcess 带有病毒扫描程序 2850

  • Windows Fork(使用 CreateProcess + fixup 模拟)大于 2850

其他测量值的数字

  • 创建文件。

    • Linux 13

    • Mac 113

    • 窗户 225

    • Raspberry-Pi(带慢速 SD 卡) 241

    • 带有防御程序和病毒扫描程序等的 Windows 12950

  • 分配内存

    • Linux 79

    • Windows 93

    • Mac 152

解决方案 9:

所有这些再加上一个事实,即在 Win 机器上,防病毒软件很可能会在 CreateProcess 期间启动……这通常是最严重的减速。

解决方案 10:

还值得注意的是,Windows 中的安全模型比基于 Unix 的操作系统复杂得多,这在进程创建期间增加了大量开销。这也是 Windows 中多线程优于多处理的另一个原因。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用