/* Tester for the kernel's speed in scheduling. (C) 1999 / Willy Tarreau Modified by Davide Libenzi You can do whatever you want with this program, but I'm not responsible for any misuse. Be aware that it can heavily load a host. As it is multithreaded, it might take advantages of SMP. It basically creates a growing amount of threads and measures their cumulative work (i.e. loop iterations/second). The output is easily useable by gnuplot. To compile, you need libpthread : gcc -O2 -fomit-frame-pointer -o threads threads.c -lpthread Output on stdout is : */ #include #include #include #include #include #define MAXTHREADS 450 #define MEASURE_TIME 30 pthread_t thr[MAXTHREADS]; int nbthreads = MAXTHREADS; int measure_time = MEASURE_TIME; volatile actthreads = 0; long long int totalwork[MAXTHREADS]; volatile int stop = 0, start = 0, count = 0; void oneatwork(int thr) { long long int counter = 0; while (!start) /* don't disturb pthread_create() */ usleep(10000); while (!stop) { if (count) ++counter; syscall(158); /* sys_sched_yield() */ } totalwork[thr] = counter; pthread_exit(0); } main(int argc, char **argv) { int i, err, avgwork, thrzero; long long int value, avgvalue; double sqrdev; time_t ts, te; start = 0; count = 0; stop = 0; actthreads = 0; thrzero = 0; value = 0; sqrdev = 0.0; fprintf(stderr, "\nCreating %d threads ...", nbthreads); for (i = 0; i < nbthreads; i++) { if ((err = pthread_create(&thr[i], NULL, (void *) &oneatwork, (void *) i)) != 0) { fprintf(stderr, "thread %d pthread_create=%d -> ", i, err); perror(""); exit(1); } pthread_detach(thr[i]); } for (i = 0; i < nbthreads; i++) totalwork[i] = 0; fprintf(stderr, " OK !\nWaiting for all threads to start ..."); start = 1; while (actthreads != nbthreads) usleep(10000); /* waiting for a bit of stability */ fprintf(stderr, "Go !\n"); count = 1; time(&ts); sleep(measure_time); count = 0; stop = 1; time(&te); for (i = 0; i < nbthreads; i++) { value += totalwork[i]; if (totalwork[i] == 0) ++thrzero; } avgvalue = value / nbthreads; value /= (int) difftime(te, ts); avgwork = (int) (value / nbthreads); for (i = 0; i < nbthreads; i++) { double difvv = (double) (totalwork[i] - avgvalue); sqrdev += difvv * difvv; } while (actthreads > 0) usleep(10000); printf("%d\t\t%lld\t\t%d\t\t%d\t\t%f\n", nbthreads, value, avgwork, thrzero, sqrdev / ((double) nbthreads * avgvalue * avgvalue)); exit(0); }