summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tune/Makefile.am27
-rw-r--r--tune/common.c126
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.