diff options
-rw-r--r-- | tune/Makefile.am | 27 | ||||
-rw-r--r-- | tune/common.c | 126 |
2 files changed, 142 insertions, 11 deletions
diff --git a/tune/Makefile.am b/tune/Makefile.am index be5b56672..513e7bae8 100644 --- a/tune/Makefile.am +++ b/tune/Makefile.am @@ -30,11 +30,13 @@ noinst_HEADERS = speed.h EXTRA_LTLIBRARIES = libspeed.la libdummy.la -libspeed_la_SOURCES = \ - common.c divrem_1_div.c divrem_1_inv.c freq.c gcd_bin.c gcd_finda_gen.c \ - gcdext_single.c gcdext_double.c gcdextod.c gcdextos.c \ - mod_1_div.c mod_1_inv.c modlinv.c mul_n_mpn.c mul_n_open.c \ - noop.c powm_mod.c powm_redc.c time.c +libspeed_la_SOURCES = \ + common.c divrem_1_div.c divrem_1_inv.c divrem_2_div.c divrem_2_inv.c \ + freq.c gcd_bin.c gcd_finda_gen.c \ + gcdext_single.c gcdext_double.c gcdextod.c gcdextos.c \ + mod_1_div.c mod_1_inv.c modlinv.c mul_n_mpn.c mul_n_open.c \ + noop.c powm_mod.c powm_redc.c time.c \ + sb_div.c sb_inv.c libspeed_la_DEPENDENCIES = $(SPEED_CYCLECOUNTER_OBJ) \ $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la @@ -99,15 +101,22 @@ DISTCLEANFILES = sqr_basecase.c # Generating these little files at build time seems better than including # them in the distribution, since the list can be changed more easily. # -# mpn/generic/tdiv_qr.c uses mpn_divrem_1, but only for a 1 limb divisor, -# which is never used during tuning, so it doesn't matter whether it picks -# up a tuned or untuned version of that routine. +# mpn/generic/tdiv_qr.c uses mpn_divrem_1 and mpn_divrem_2, but only for 1 +# and 2 limb divisors, which are never used during tuning, so it doesn't +# matter whether it picks up a tuned or untuned version of those. +# +# divrem_1 and mod_1 are recompiled renamed to "_tune" to avoid a linking +# problem. If a native divrem_1 provides an mpn_divrem_1c entrypoint then +# common.c will want that, but the generic divrem_1 doesn't provide it, +# likewise for mod_1. The simplest way around this is to have the tune +# build versions renamed suitably. # # FIXME: Would like say mul_n.c to depend on $(top_builddir)/mul_n.c so the # recompiled object will be rebuilt if that file changes. TUNE_MPN_SRCS = $(TUNE_MPN_SRCS_BASIC) divrem_1.c mod_1.c -TUNE_MPN_SRCS_BASIC = dc_divrem_n.c gcd.c mul_n.c mul_fft.c mul.c tdiv_qr.c +TUNE_MPN_SRCS_BASIC = dc_divrem_n.c divrem_2.c gcd.c mul_n.c mul_fft.c mul.c \ + sb_divrem_mn.c tdiv_qr.c TUNE_MPZ_SRCS = fib_ui.c $(TUNE_MPN_SRCS_BASIC): diff --git a/tune/common.c b/tune/common.c index a6da5d7d6..4505ceb0b 100644 --- a/tune/common.c +++ b/tune/common.c @@ -532,6 +532,16 @@ speed_mpn_divrem_2 (struct speed_params *s) { SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2); } +double +speed_mpn_divrem_2_div (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2_div); +} +double +speed_mpn_divrem_2_inv (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_DIVREM_2 (mpn_divrem_2_inv); +} double speed_mpn_mod_1 (struct speed_params *s) @@ -574,6 +584,11 @@ speed_mpn_modexact_1c_odd (struct speed_params *s) double +speed_mpn_dc_tdiv_qr (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_DC_TDIV_QR (mpn_tdiv_qr); +} +double speed_mpn_dc_divrem_n (struct speed_params *s) { SPEED_ROUTINE_MPN_DC_DIVREM_N (mpn_dc_divrem_n); @@ -584,10 +599,32 @@ speed_mpn_dc_divrem_sb (struct speed_params *s) SPEED_ROUTINE_MPN_DC_DIVREM_SB (mpn_sb_divrem_mn); } double -speed_mpn_dc_tdiv_qr (struct speed_params *s) +speed_mpn_dc_divrem_sb_div (struct speed_params *s) { - SPEED_ROUTINE_MPN_DC_TDIV_QR (mpn_tdiv_qr); + SPEED_ROUTINE_MPN_DC_DIVREM_SB (mpn_sb_divrem_mn_div); +} +double +speed_mpn_dc_divrem_sb_inv (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_DC_DIVREM_SB (mpn_sb_divrem_mn_inv); } + +double +speed_mpn_sb_divrem_m3 (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_SB_DIVREM_M3 (mpn_sb_divrem_mn); +} +double +speed_mpn_sb_divrem_m3_div (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_SB_DIVREM_M3 (mpn_sb_divrem_mn_div); +} +double +speed_mpn_sb_divrem_m3_inv (struct speed_params *s) +{ + SPEED_ROUTINE_MPN_SB_DIVREM_M3 (mpn_sb_divrem_mn_inv); +} + double speed_mpz_mod (struct speed_params *s) { @@ -1471,6 +1508,91 @@ speed_invert_limb (struct speed_params *s) } +/* xp[0] might not be particularly random, but should give an indication how + "/" runs. Same for speed_operator_mod below. */ +double +speed_operator_div (struct speed_params *s) +{ + double t; + unsigned i; + mp_limb_t x, q, d; + + s->time_divisor = 10; + + /* divisor from "r" parameter, or a default */ + d = s->r; + if (d == 0) + d = __mp_bases[10].big_base; + + x = s->xp[0]; + q = 0; + + speed_starttime (); + i = s->reps; + do + { + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + q ^= x; q /= d; + } + while (--i != 0); + t = speed_endtime (); + + /* stop the compiler optimizing away the whole calculation! */ + noop_1 (q); + + return t; +} + +double +speed_operator_mod (struct speed_params *s) +{ + double t; + unsigned i; + mp_limb_t x, r, d; + + s->time_divisor = 10; + + /* divisor from "r" parameter, or a default */ + d = s->r; + if (d == 0) + d = __mp_bases[10].big_base; + + x = s->xp[0]; + r = 0; + + speed_starttime (); + i = s->reps; + do + { + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + r ^= x; r %= d; + } + while (--i != 0); + t = speed_endtime (); + + /* stop the compiler optimizing away the whole calculation! */ + noop_1 (r); + + return t; +} + + /* r==0 measures on data with the values uniformly distributed. This will be typical for count_trailing_zeros in a GCD etc. |