Dear GMP developers, below is a patch (against GMP 6.1.1) that allows to measure the basic mpf functions using speed (with -s in bits):
$ ./speed -p1000000000 -c -s 113 mpf_add mpf_sub mpf_mul mpf_div mpf_sqrt overhead 3.56 cycles, precision 1000000000 units of 1.25e-09 secs, CPU freq 800.13 MHz mpf_add mpf_sub mpf_mul mpf_div mpf_sqrt 113 #45.00 48.36 46.30 145.90 352.58 I contribute this patch to GMP, but most probably you can improve it. Best regards, Paul --- common.c.orig 2016-09-01 15:48:21.378349300 +0200 +++ common.c 2016-09-01 16:34:24.035003662 +0200 @@ -1998,6 +1998,152 @@ mpf_clear (f)); } +double +speed_mpf_add (struct speed_params *s) +{ + mpf_t w, x, y; + unsigned i; + double t; + + mpf_init2 (w, s->size); + mpf_init2 (x, s->size); + mpf_init2 (y, s->size); + + mpf_random2 (x, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_random2 (y, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_add (w, x, y); + + speed_starttime (); + i = s->reps; + do + { + mpf_add (w, x, y); + } + while (--i != 0); + t = speed_endtime (); + + mpf_clear (w); + mpf_clear (x); + mpf_clear (y); + return t; +} + +double +speed_mpf_sub (struct speed_params *s) +{ + mpf_t w, x, y; + unsigned i; + double t; + + mpf_init2 (w, s->size); + mpf_init2 (x, s->size); + mpf_init2 (y, s->size); + + mpf_random2 (x, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_random2 (y, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_sub (w, x, y); + + speed_starttime (); + i = s->reps; + do + { + mpf_sub (w, x, y); + } + while (--i != 0); + t = speed_endtime (); + + mpf_clear (w); + mpf_clear (x); + mpf_clear (y); + return t; +} + +double +speed_mpf_mul (struct speed_params *s) +{ + mpf_t w, x, y; + unsigned i; + double t; + + mpf_init2 (w, s->size); + mpf_init2 (x, s->size); + mpf_init2 (y, s->size); + + mpf_random2 (x, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_random2 (y, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_mul (w, x, y); + + speed_starttime (); + i = s->reps; + do + { + mpf_mul (w, x, y); + } + while (--i != 0); + t = speed_endtime (); + + mpf_clear (w); + mpf_clear (x); + mpf_clear (y); + return t; +} + +double +speed_mpf_div (struct speed_params *s) +{ + mpf_t w, x, y; + unsigned i; + double t; + + mpf_init2 (w, s->size); + mpf_init2 (x, s->size); + mpf_init2 (y, s->size); + + mpf_random2 (x, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_random2 (y, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_div (w, x, y); + + speed_starttime (); + i = s->reps; + do + { + mpf_div (w, x, y); + } + while (--i != 0); + t = speed_endtime (); + + mpf_clear (w); + mpf_clear (x); + mpf_clear (y); + return t; +} + +double +speed_mpf_sqrt (struct speed_params *s) +{ + mpf_t w, x; + unsigned i; + double t; + + mpf_init2 (w, s->size); + mpf_init2 (x, s->size); + + mpf_random2 (x, 1 + (s->size - 1) / GMP_NUMB_BITS, 0); + mpf_sqrt (w, x); + + speed_starttime (); + i = s->reps; + do + { + mpf_sqrt (w, x); + } + while (--i != 0); + t = speed_endtime (); + + mpf_clear (w); + mpf_clear (x); + return t; +} /* Compare this to mpn_add_n to see how much overhead mpz_add adds. Note that repeatedly calling mpz_add with the same data gives branch prediction --- speed.c.orig 2016-09-01 15:48:04.174345004 +0200 +++ speed.c 2016-09-01 15:40:37.746232291 +0200 @@ -509,6 +509,11 @@ { "mpz_init_clear", speed_mpz_init_clear }, { "mpq_init_clear", speed_mpq_init_clear }, { "mpf_init_clear", speed_mpf_init_clear }, + { "mpf_add", speed_mpf_add }, + { "mpf_sub", speed_mpf_sub }, + { "mpf_mul", speed_mpf_mul }, + { "mpf_div", speed_mpf_div }, + { "mpf_sqrt", speed_mpf_sqrt }, { "mpz_init_realloc_clear", speed_mpz_init_realloc_clear }, { "umul_ppmm", speed_umul_ppmm, FLAG_R_OPTIONAL }, --- speed.h.orig 2016-09-01 15:48:10.370346551 +0200 +++ speed.h 2016-09-01 15:37:47.686188699 +0200 @@ -153,6 +153,11 @@ double speed_binvert_limb_arith (struct speed_params *); double speed_mpf_init_clear (struct speed_params *); +double speed_mpf_add (struct speed_params *); +double speed_mpf_sub (struct speed_params *); +double speed_mpf_mul (struct speed_params *); +double speed_mpf_div (struct speed_params *); +double speed_mpf_sqrt (struct speed_params *); double speed_mpn_add_n (struct speed_params *); double speed_mpn_add_1 (struct speed_params *); _______________________________________________ gmp-devel mailing list gmp-devel@gmplib.org https://gmplib.org/mailman/listinfo/gmp-devel