lkml.org 
[lkml]   [2004]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: Linux 2.4 VS 2.6 fork VS thread creation time test
    Gergely Czuczy wrote:
    > -----BEGIN PGP SIGNED MESSAGE-----
    > Hash: SHA1
    >
    > Hello everyone,
    >
    > Today morning I've made a test about the thead and child process
    > creation(fork) time on both 2.4 and 2.6 kernels.
    >
    > The test systems
    > ================
    >
    > Box A:
    > - kernel: Linux 2.4.22-xfs
    > - CPU: Intel P3-700 MHz (slot1)
    > - Ram: 384MB SDR SDRAM
    >
    > Box B:
    > - kernel: Linux 2.6.6-mm5
    > - CPU: Intel P4-2.6Ghz
    > - Ram: 512 DDR SDRAM
    >
    > Box B is a lot better, but it doesn't metter according to the test,
    > because the aim was to get the ratio of the two times with different
    > sample rates.
    >

    Even so, you really should be using the same system if you want
    comparable results. The pentium 4 in particular can do worse at
    specific things in microbenchmarks.

    Your problem with not being able large numbers of threads and
    processes could be ulimits or sysctl limits. Look at ulimit
    and /proc/sys/kernel/threads-max and pid_max.

    [ snip numbers ]

    > Conlusion
    > =========
    >
    > It's easy to notice that in case of 2.4 the ratios of the creation times
    > are converges to 1, so it depends on the load, while in case of a 2.6
    > kernel the ratios are mostly fix, about 9. This means that creating a new
    > child process takes much more time than creating a new thread.
    >

    I tried your code on a P3-1000. 2.4.23 is not 100% comparable because it
    was built with an old compiler and possibly different options.

    Anyway, results with 256 samples were as follows:
    processes 256
    2.4.23:
    Total fork time: 48.224 msecs
    Total thread time: 30.180 msecs
    Total fork/thread ratio: 1.598

    2.6.6-mm5:
    Total fork time: 40.795 msecs
    Total thread time: 17.615 msecs
    Total fork/thread ratio: 2.316

    2.6.6-mm5+child-runs-last:
    Total fork time: 16.080 msecs
    Total thread time: 8.600 msecs
    Total fork/thread ratio: 1.870

    2.6 introduced an optimisation called child-runs-first. Apparently
    it is nice for many common things, but it also causes a context
    switch at every fork(), so sucks for these microbenchmarks. Child-
    runs-last simply reverts that. Patch is attached if anyone is
    interested.
    linux-2.6-npiggin/kernel/fork.c | 7 +------
    linux-2.6-npiggin/kernel/sched.c | 20 ++------------------
    2 files changed, 3 insertions(+), 24 deletions(-)

    diff -puN kernel/sched.c~no-child-run-first kernel/sched.c
    --- linux-2.6/kernel/sched.c~no-child-run-first 2004-05-23 18:22:41.000000000 +1000
    +++ linux-2.6-npiggin/kernel/sched.c 2004-05-23 18:22:41.000000000 +1000
    @@ -1073,15 +1073,7 @@ void fastcall wake_up_forked_process(tas
    p->prio = effective_prio(p);
    set_task_cpu(p, smp_processor_id());

    - if (unlikely(!current->array))
    - __activate_task(p, rq);
    - else {
    - p->prio = current->prio;
    - list_add_tail(&p->run_list, &current->run_list);
    - p->array = current->array;
    - p->array->nr_active++;
    - rq->nr_running++;
    - }
    + __activate_task(p, rq);
    task_rq_unlock(rq, &flags);
    }

    @@ -1395,15 +1387,7 @@ lock_again:
    set_task_cpu(p, cpu);

    if (cpu == this_cpu) {
    - if (unlikely(!current->array))
    - __activate_task(p, rq);
    - else {
    - p->prio = current->prio;
    - list_add_tail(&p->run_list, &current->run_list);
    - p->array = current->array;
    - p->array->nr_active++;
    - rq->nr_running++;
    - }
    + __activate_task(p, rq);
    } else {
    schedstat_inc(sd, sbc_pushed);
    /* Not the local CPU - must adjust timestamp */
    diff -puN kernel/fork.c~no-child-run-first kernel/fork.c
    --- linux-2.6/kernel/fork.c~no-child-run-first 2004-05-23 18:22:41.000000000 +1000
    +++ linux-2.6-npiggin/kernel/fork.c 2004-05-23 18:22:41.000000000 +1000
    @@ -1239,12 +1239,7 @@ long do_fork(unsigned long clone_flags,
    wait_for_completion(&vfork);
    if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE))
    ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
    - } else
    - /*
    - * Let the child process run first, to avoid most of the
    - * COW overhead when the child exec()s afterwards.
    - */
    - set_need_resched();
    + }
    }
    return pid;
    }
    _
    \
     
     \ /
      Last update: 2005-03-22 14:03    [W:0.025 / U:0.204 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site