|
|
Subscribe / Log in / New account

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

I am not sure if it copies the entire page table, but the effect is noticeable: http://hxbc.us/software/fork_bench.c (try running it with different c and n)


to post comments

why not posix_spawn()?

Posted Nov 6, 2009 6:12 UTC (Fri) by mikov (guest, #33179) [Link] (4 responses)

You are absolutely right. Here are my results:
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

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 ):
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.

Then I restored the malloc(), but replaced the fork() with vfork():
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

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?

why not posix_spawn()?

Posted Nov 6, 2009 19:12 UTC (Fri) by khc (guest, #45209) [Link] (1 responses)

you are right that the speed of fork() is seldom noticeable in a GUI program, but it bites me all the time in daemons (big daemon wanting to launch many processes, one by one, do do some tasks). vfork() is too limiting because all you can do after is exec(), but sometimes you do want to extra flexibility that posix_spawn can provide.

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.

why not posix_spawn()?

Posted Nov 6, 2009 19:28 UTC (Fri) by mikov (guest, #33179) [Link]

I am not sure what you mean. Unless I am missing something, vfork() is much more flexible and easier to use than posix_spawn().

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.

why not posix_spawn()?

Posted Nov 6, 2009 22:55 UTC (Fri) by cmccabe (guest, #60281) [Link]

> Any good reasons why vfork() should be avoided?

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.

why not posix_spawn()?

Posted Nov 6, 2009 23:23 UTC (Fri) by cmccabe (guest, #60281) [Link]

> Any good reasons why vfork() should be avoided?

Ah. Found it.

https://www.securecoding.cert.org/confluence/display/secc...

> Due to the implementation of the vfork() function, the parent process is
> 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.

clone(CLONE_VM) + exec might be the win...

Colin


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds