Date: 25 Jun 2003 06:06:29 -0000 From: "D. J. Bernstein" <djb@cr.yp.to> To: freebsd-performance@freebsd.org Subject: Re: ten thousand small processes Message-ID: <20030625060629.51087.qmail@cr.yp.to> References: <20030623030004.40078.qmail@cr.yp.to> <20030624203536.D17881-100000@mail.chesapeake.net>
index | next in thread | previous in thread | raw e-mail
As I said, I don't particularly care about the text segment. I'm not
talking about ten thousand separate programs.
Why does the memory manager keep the stack separate from data? Suppose a
program has 1000 bytes of data+bss. You could organize VM as follows:
0x7fffac18 0x7fffb000 0x80000000
<---- stack data+bss text, say 5 pages heap ---->
As long as the stack doesn't chew up more than 3096 bytes and the heap
isn't used, there's just one page per process.
As for page tables: Instead of allocating space for a bunch of nearly
identical page tables, why not overlap page tables, with the changes
copied on a process switch?
As for 39 pages of VM, mostly stack: Can the system actually allocate
390000 pages of VM? I'm only mildly concerned with the memory-management
time; what bothers me is the loss of valuable address space. I hope that
this 128-kilobyte stack carelessness doesn't reflect a general policy of
dishonest VM allocation (``overcommitment''); I need to be able to
preallocate memory with proper error detection, so that I can guarantee
the success of subsequent operations.
As for malloc()'s careless use of memory: Is it really asking so much
that a single malloc(1) not be expanded by a factor of 16384?
Here's a really easy way to improve malloc(). Apparently, right now,
there's no use of the space between the initial brk and the next page
boundary. Okay: allocate that space in the simplest possible way---
static wherewenormallystart = 0;
static freebie;
malloc(n)
{
if (!wherewenormallystart) {
wherewenormallystart = rounduptopage(sbrk(0));
freebie = wherewenormallystart - rounduptoalign(sbrk(0));
}
n = rounduptoalign(n);
if (n < freebie) {
freebie -= n;
if (sbrk(0) <= wherewenormallystart) brk(wherewenormallystart - freebie);
return wherewenormallystart - freebie - n;
}
do what we normally do;
}
free(x)
{
if (x < wherewenormallystart) return;
do what we normally do;
}
---with no waste of space and practically no waste of time. Maybe add
8192 to wherewenormallystart; this is lots of room for people who know
how to write small programs, and the cost is unnoticeable for people who
don't.
(Quite a few of my programs simulate this effect by checking for space
in a bss array, typically 2K. But setting aside the right amount of
space would mean compiling, inspecting the brk alignment, and
recompiling. I also feel bad chewing up space on systems where malloc()
actually knows what it's doing.)
As for the safety of writing code that makes malloc() fail horribly:
After the Solaris treatment of BSD sockets, and the ``look, Ma, I can
make an only-slightly-broken imitation of poll() using select()!''
epidemic, I don't trust OS distributors to reserve syscall names for
actual syscalls. I encounter more than enough portability problems
without going out of my way to look for them.
---D. J. Bernstein, Associate Professor, Department of Mathematics,
Statistics, and Computer Science, University of Illinois at Chicago
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030625060629.51087.qmail>
