/* timegauss.c - measure the speed of random number generation * * Copyright (C) 2005 Jochen Voss. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include extern double gsl_ran_gaussian_ziggurat (gsl_rng *r, const double sigma); extern double gsl_ran_gaussian2 (gsl_rng *r, const double sigma); extern double gsl_ran_gaussian3 (gsl_rng *r, const double sigma); static sigjmp_buf leave_loop; static void handle_alarm (int signum) { siglongjmp (leave_loop, 1); } static unsigned long count_calls (gsl_rng *rng, double (*f)(gsl_rng *, const double)) { volatile unsigned long n = 0; struct itimerval pause; pause.it_interval.tv_usec = 0; pause.it_interval.tv_sec = 0; pause.it_value.tv_usec = 0; pause.it_value.tv_sec = 1; signal (SIGVTALRM, handle_alarm); if (sigsetjmp (leave_loop, 1) == 0) { if (setitimer (ITIMER_VIRTUAL, &pause, NULL) < 0) abort (); while (1) { f (rng, 1); ++n; } } return n; } static void test_with_rng (const gsl_rng_type *T, FILE *res) { gsl_rng *rng = gsl_rng_alloc (T); unsigned long c1, c2, c3; /* generated numbers / second */ double m1, m2, m3; /* averages */ double q; int i; printf ("testing with %s:\n", T->name); m1 = m2 = m3 = 0; for (i=0; i<=10; ++i) { c1 = count_calls (rng, gsl_ran_gaussian_ziggurat); c2 = count_calls (rng, gsl_ran_gaussian2); c3 = count_calls (rng, gsl_ran_gaussian3); printf (" %lu %lu %lu numbers/second\n", c1, c2, c3); if (i>0) { m1 += c1; m2 += c2; m3 += c3; } } q = m1 / (m2>m3 ? m2 : m3); fprintf (res, "%s%.3g%.3g%.3g%.1f\n", T->name, m1/10.0e6, m2/10.0e6, m3/10.0e6, q); fflush (NULL); gsl_rng_free (rng); } int main () { const gsl_rng_type **t, **t0; FILE *res; res = fopen ("data.html", "w"); gsl_rng_env_setup(); t0 = gsl_rng_types_setup (); for (t = t0; *t != 0; t++) { test_with_rng (*t, res); } fclose (res); return 0; }