lkml.org 
[lkml]   [2004]   [May]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectLinux 2.4 VS 2.6 fork VS thread creation time test
-----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.

The sample rates
================

I've chosen a low, a middle and a higher sample rate for the test, they
was 20,128 and 255 samples.
Notice in the attached source that every child processes and threads are
terminated right after creation, and only the creation function call is
timed. It was interesting that when I've chosed a _very_ high sample rate,
about 10^8 there was a lot of failures, the kernel could only create about
4K child processes, and after this all the thread creations failed. As I
told it above all the processes are teminated right after creation, but
there were a lot of defunct processes in the system, and they were only
gone when the parent termineted.
With a few number of processes I wasn't able to go over 255 threads,
after the 255th every creation attempt simply failed.

The test outputs
================

Box A, 20 samples:
- ------------------
Fork failures: 0 (success: 20)
Avarage fork time: 0.326800 msecs
Total fork time: 6.536000 msecs
Thread failures: 0 (success: 20)
Avarage thread time: 0.075550 msecs
Total thread time: 1.511000 msecs
Avarage fork/thread ratio: 4.325612
Total fork/thread ratio: 4.325612

Box A, 128 samples:
- ------------------
Fork failures: 0 (success: 128)
Avarage fork time: 0.332773 msecs
Total fork time: 42.595000 msecs
Thread failures: 0 (success: 128)
Avarage thread time: 0.084859 msecs
Total thread time: 10.862000 msecs
Avarage fork/thread ratio: 3.921469
Total fork/thread ratio: 3.921469

Box A, 255 samples:
- -------------------
Fork failures: 0 (success: 255)
Avarage fork time: 0.344827 msecs
Total fork time: 87.931000 msecs
Thread failures: 0 (success: 255)
Avarage thread time: 0.209718 msecs
Total thread time: 53.478000 msecs
Avarage fork/thread ratio: 1.644246
Total fork/thread ratio: 1.644246

Box B, 20 samples:
- ------------------
Fork failures: 0 (success: 20)
Avarage fork time: 0.257900 msecs
Total fork time: 5.158000 msecs
Thread failures: 0 (success: 20)
Avarage thread time: 0.026850 msecs
Total thread time: 0.537000 msecs
Avarage fork/thread ratio: 9.605214
Total fork/thread ratio: 9.605214

Box B, 128 samples:
- -------------------
Fork failures: 0 (success: 128)
Avarage fork time: 0.242633 msecs
Total fork time: 31.057000 msecs
Thread failures: 0 (success: 128)
Avarage thread time: 0.025859 msecs
Total thread time: 3.310000 msecs
Avarage fork/thread ratio: 9.382779
Total fork/thread ratio: 9.382779

Box B, 255 samples:
- -------------------
Fork failures: 0 (success: 255)
Avarage fork time: 0.241678 msecs
Total fork time: 61.628000 msecs
Thread failures: 0 (success: 255)
Avarage thread time: 0.025729 msecs
Total thread time: 6.561000 msecs
Avarage fork/thread ratio: 9.393080
Total fork/thread ratio: 9.393080

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.


Bye,

Gergely Czuczy
mailto: phoemix@harmless.hu
PGP: http://phoemix.harmless.hu/phoemix.pgp

"Wish a god, a star to believe in,
With the realm of king of fantasy..."
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAsFmObBsEN0U7BV0RAiawAJ93KmDqYwksMNGci11hOdLbr2rXWwCfdcZR
cv1WcImKLpNOfNr9pdqyfm0=
=2yxd
-----END PGP SIGNATURE-----
/*
Test how much time is needed for a process/thread creation
Author: Gergely Czuczy <phoemix@harmless.hu>
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/time.h>


double timeval2double(struct timeval *_tv);
void *threadfunc(void *);

/*
================================
int main(int argc, char *argv[])
================================
*/
int main(int argc, char *argv[]) {
unsigned int i;
unsigned int samples;
unsigned int forkfailures(0), threadfailures(0);
double totalforktime(0),totalthreadtime(0), forktime, threadtime;
struct timeval begin,end,diff;
pid_t childpid;
pthread_t thread;

if ( argc != 2 ) {
printf("Usage:\n\t%s <number of samples>\n", argv[0]);
return EXIT_FAILURE;
}

// we get the number of samples to take
samples = atoi(argv[1]);

// test the forks
printf("\n");
for ( i=0; i<samples; ++i ) {
printf("\rFork test: %u/%u (%3.2f%%)", i+1, samples, ((i+1.0)/samples)*100);fflush(0);

gettimeofday(&begin, 0);
childpid = fork();
gettimeofday(&end, 0);

if ( !childpid ) _exit(0);
if ( childpid==-1 ) ++forkfailures;

timersub(&end, &begin, &diff);
totalforktime += timeval2double(&diff);
usleep(1);
}
printf("\n");

usleep(10000);

// test the threads
printf("\n");
for ( i=0; i<samples; ++i ) {
int ret;

printf("\rThread test: %u/%u (%3.2f%%)", i+1, samples, ((i+1.0)/samples)*100);fflush(0);

gettimeofday(&begin, 0);
ret = pthread_create(&thread, 0, &threadfunc, 0);
gettimeofday(&end, 0);

if ( ret ) ++threadfailures;

timersub(&end, &begin, &diff);
totalthreadtime += timeval2double(&diff);
usleep(1);
}
printf("\n\n");


// print the results
forktime = totalforktime / (samples-forkfailures);
printf("Fork failures: %u (succes: %u)\n", forkfailures, samples-forkfailures);
printf("Avarage fork time: %5f msecs\n", forktime);
printf("Total fork time: %5f msecs\n", totalforktime);
threadtime = totalthreadtime / (samples-threadfailures);
printf("Thread failures: %u (success: %u)\n", threadfailures, samples-threadfailures);
printf("Avarage thread time: %5f msecs\n", threadtime);
printf("Total thread time: %5f msecs\n", totalthreadtime);
printf("Avarage fork/thread ratio: %2f\n", forktime/threadtime);
printf("Total fork/thread ratio: %2f\n", totalforktime/totalthreadtime);

return EXIT_SUCCESS;
}

/*
============================
void *threadfunc(void *_arg)
============================
*/
void *threadfunc(void *) {
pthread_exit(0);
return 0;
}

/*
==========================================
double timeval2double(struct timeval *_tv)
==========================================
*/
double timeval2double(struct timeval *_tv) {
double ret;
ret = _tv->tv_usec;
ret /= 1000000;
ret += _tv->tv_sec;
ret *= 1000;
return ret;
}
\
 
 \ /
  Last update: 2005-03-22 14:03    [W:0.380 / U:0.104 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site