During the Christmas holidays in 1989, I ran a little benchmark
(`forktime') on various machines.  The program was roughly

        loop many times
                fork
                parent waits
                child exits

I ran it twice or more linked statically and twice or more linked
dynamically on each machine.  The machines were lightly loaded.  For
1000 iterations, user time is consistently about 100ms for
statically-linked forktime, but 4-11 times that when dynamically
linked (i.e., using shared libraries).

System times are more interesting.  SunOS 3.5 had no shared libraries,
so Sun seems to have sped up fork() by about 50% between SunOS 3.5 and
4.0 for statically-linked programs, but then lost all that performance
and more when using shared libraries on 4.0, which took almost 4 times
as much system time as statically-linked forktime on 4.0.

We scratched our heads about what in the world the kernel was doing
for 42ms per fork.  Even on a Sun 3/50, that's a lot of cycles.

This was a long time ago, but it's some actual measurements.

--- fork times ---
: utubrutus; time ./forktime 1000       # sun 3/50 sunos 3.5 diskless
       22.9 real         0.1 user        22.0 sys
       22.6 real         0.1 user        22.1 sys

: nil.ai; time 3s/forktime 1000         # sun 3/50 sunos 4.0 diskless -Bstatic
       12.0 real         0.1 user        11.7 sys
       11.9 real         0.1 user        11.7 sys
: nil.ai; time 3/forktime 1000          # sun 3/50 sunos 4.0 diskless dynamic
       46.8 real         0.8 user        41.7 sys
       46.9 real         1.1 user        42.4 sys
       45.9 real         0.9 user        42.2 sys

: neat.cs; time 4s/forktime 1000        # sun 4/280 sunos 4.0 -Bstatic
       12.7 real         0.1 user        11.8 sys
       12.0 real         0.1 user        11.2 sys
: neat.cs; time 4/forktime 1000         # sun 4/280 sunos 4.0 dynamic
       29.9 real         0.4 user        25.3 sys
       35.4 real         0.5 user        25.0 sys

---
/*
 * forktime - execute many forks for timing
 */

#define NULL 0

/* imports */
long atol();

main(argc, argv)
int argc;
char **argv;
{
        register long count = 1000;

        if (argc > 1)
                count = atol(argv[1]);
        while (count-- > 0) {
                register int pid = fork();

                if (pid < 0)
                        perror(argv[0]);
                else if (pid == 0)      /* child */
                        _exit(0);
                else {
                        register int deadpid;

                        while ((deadpid = wait((int *)NULL)) != pid && deadpid 
!= -1)
                                ;
                }
        }
        _exit(0);
}

Reply via email to