why not posix_spawn()?
why not posix_spawn()?
Posted Nov 6, 2009 1:17 UTC (Fri) by khc (guest, #45209)In reply to: why not posix_spawn()? by mikov
Parent article: Toward a smarter OOM killer
Posted Nov 6, 2009 6:12 UTC (Fri)
by mikov (guest, #33179)
[Link] (4 responses)
With a heap of 1G it takes 33ms to do a fork() on my machine, which to me is surprisingly long (although not that surprising when you consider the mere size of the 4KB page tables). While, as I said initially, it would definitely not be noticeable for interactive process creation, it is significant. The mach maligned "slow" process creation on Windows is much faster for sure...
I did run a couple of more tests though, which improve the situation. First I confirmed that the page tables of shared memory mappings really are not copied. I replaced the malloc() with mmap( MAP_ANON | MAP_SHARED ):
Then I restored the malloc(), but replaced the fork() with vfork():
The last result is really encouraging (and actually not surprising). Even though everybody seems to hate vfork(), for the case we are discussing (fork of a huge address space + exec), it should solve all problems, removing the need for the clumsy posix_spawn(), while preserving all the flexibility of fork(). Beat that, Windows!
Any good reasons why vfork() should be avoided?
Posted Nov 6, 2009 19:12 UTC (Fri)
by khc (guest, #45209)
[Link] (1 responses)
I have to admit that I have never checked to see if posix_spawn fits my need, though. Since I only care about linux and posix_spawn on linux is the same as fork()/.../exec(), it's useless for me anyway.
Posted Nov 6, 2009 19:28 UTC (Fri)
by mikov (guest, #33179)
[Link]
If your purpose is to call exec() after fork(), you should just be able to mechanically replace all forks() with vforks() and get a big boost.
Posted Nov 6, 2009 22:55 UTC (Fri)
by cmccabe (guest, #60281)
[Link]
The manual page installed on my system says that copy-on-write makes vfork unecessary. It concludes with "it is rather unfortunate that Linux revived this specter from the past." :)
However... it seems like the results you've posted show quite a substantial performance gain for vfork + exec as opposed to fork + exec, for processes with large heaps.
Maybe the "preferred" way to do this on Linux would be using clone(2)??
C.
Posted Nov 6, 2009 23:23 UTC (Fri)
by cmccabe (guest, #60281)
[Link]
Ah. Found it.
https://www.securecoding.cert.org/confluence/display/secc...
> Due to the implementation of the vfork() function, the parent process is
clone(CLONE_VM) + exec might be the win...
Colin
why not posix_spawn()?
malloc(1MB) 3235 ms 0.161750 ms/iter
malloc(100MB) 390 ms 3.900000 ms/iter
malloc(500MB) 1663 ms 16.630000 ms/iter
malloc(1024MB) 3329 ms 33.290000 ms/iter
mmap(1MB) 1204 ms 0.120400 ms/iter
mmap(100MB) 1201 ms 0.120100 ms/iter
mmap(500MB) 1231 ms 0.123100 ms/iter
mmap(1024MB) 1229 ms 0.122900 ms/iter
As you can see, there is no relation between fork() speed and mapping size.
vfork+malloc(1MB) 102 ms 0.010200 ms/iter
vfork+malloc(100MB) 107 ms 0.010700 ms/iter
vfork+malloc(500MB) 105 ms 0.010500 ms/iter
vfork+malloc(1000MB) 106 ms 0.010600 ms/iter
why not posix_spawn()?
why not posix_spawn()?
why not posix_spawn()?
why not posix_spawn()?
> suspended while the child process executes. If a user sends a signal to
> the child process, delaying its execution, the parent process (which is
> privileged) is also blocked. This means that an unprivileged process can
> cause a privileged process to halt, which is a privilege inversion
> resulting in a denial of service.
