Messages in this thread | | | Date | Sun, 23 May 2004 09:57:56 +0200 (CEST) | From | Gergely Czuczy <> | Subject | Linux 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; }
| |