什么是现代的Linux实现的同样的效果最快,最好的方法fork
- execve
组合从一个大的过程?
我的问题是,分叉过程大约为500MBy,并且一个简单的基准测试只能从该过程中获得大约50个分叉/秒(参见最小尺寸过程的~10000分叉/秒),这对于预期的应用来说太慢了.
一些谷歌搜索出现了,vfork
因为它被发明为这个问题的解决方案......但也警告不要使用它.现代Linux似乎已经获得了相关clone
和posix_spawn
呼叫; 这些可能会有所帮助吗?什么是现代的替代品vfork
?
我在i7上使用64位Debian Lenny(如果posix_spawn
有帮助,该项目可以转移到Squeeze ).
在Linux上,您可以使用posix_spawn(2)
该POSIX_SPAWN_USEVFORK
标志来避免在从大型进程分叉时复制页表的开销.
有关创建应用程序子进程的详细信息,请参阅最小化内存使用情况,以获取posix_spawn(2)
其优点和一些示例.
要利用vfork(2)
,请确保您#define _GNU_SOURCE
之前#include
和之后posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK)
我可以确认这适用于Debian Lenny,并且在从大型进程分叉时提供了大量的加速.
benchmarking the various spawns over 1000 runs at 100M RSS user system total real fspawn (fork/exec): 0.100000 15.460000 40.570000 ( 41.366389) pspawn (posix_spawn): 0.010000 0.010000 0.540000 ( 0.970577)
结果:我打算按照其他答案的建议进入早期产生的辅助子进程路径,但后来我发现这一点使用巨大的页面支持来提高fork性能.
我自己尝试使用libhugetlbfs来简单地让我所有的应用程序的mallocs分配大页面,我现在得到大约2400个分叉/秒,无论进程大小(无论如何我都感兴趣的范围).惊人.
你真的测量了叉子需要多长时间吗?引用您链接的页面,
Linux从未遇到过这个问题; 因为Linux内部使用了写时复制语义,Linux只会在页面发生变化时复制页面(实际上,仍有一些表需要复制;在大多数情况下,它们的开销并不重要)
因此,分叉的数量并没有真正显示开销有多大.您应该测量叉子所消耗的时间,并且(这是一般建议)仅由您实际执行的叉子消耗,而不是通过对最大性能进行基准测试.
但是如果你真的发现分支大的进程很慢,你可能会产生一个小的辅助进程,管道主进程到它的输入,并exec
从中接收命令.小进程将fork
和exec
这些命令.
据我所知,这个功能是通过fork
/ exec
在桌面系统上实现的.但是,在嵌入式系统中(特别是在没有MMU的系统中),进程是通过系统调用,接口posix_spawn
或类似功能产生的.引用POSIX标准posix_spawn
的信息部分描述:
对于实时环境,交换通常太慢.
在POSIX可能有用的任何地方都无法使用动态地址转换.
只要必须在没有地址转换或其他MMU服务的情况下运行,进程就无法简单地选择POSIX.
因此,POSIX需要进程创建和文件执行原语,这些原语可以在没有地址转换或其他MMU服务的情况下有效地实现.
如果您的目标是最大限度地减少时间消耗,我认为您不会从桌面上的此功能中受益.