~ chicken-core (chicken-5) 6140fe4d060fa56fa27b8d5781c762ab6eea87c7
commit 6140fe4d060fa56fa27b8d5781c762ab6eea87c7 Author: Peter Bex <peter@more-magic.net> AuthorDate: Sun Mar 22 14:47:02 2015 +0100 Commit: Peter Bex <peter@more-magic.net> CommitDate: Sun May 31 14:55:24 2015 +0200 Make bignum-extract-digits inlineable, to improve Karatsuba and Burnikel-Ziegler perf. diff --git a/chicken.h b/chicken.h index d89f88e4..4f6c6ab8 100644 --- a/chicken.h +++ b/chicken.h @@ -1974,7 +1974,6 @@ C_fctexport void C_ccall C_basic_divrem(C_word c, C_word self, C_word k, C_word C_fctexport void C_ccall C_u_integer_divrem(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; C_fctexport void C_ccall C_u_flo_to_int(C_word c, C_word self, C_word k, C_word x) C_noret; C_fctexport void C_ccall C_u_integer_shift(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; -C_fctexport void C_ccall C_u_bignum_extract_digits(C_word c, C_word self, C_word k, C_word x, C_word start, C_word end) C_noret; C_fctexport void C_ccall C_u_2_integer_bitwise_and(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; C_fctexport void C_ccall C_u_2_integer_bitwise_ior(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; C_fctexport void C_ccall C_u_2_integer_bitwise_xor(C_word c, C_word self, C_word k, C_word x, C_word y) C_noret; @@ -2190,6 +2189,7 @@ C_fctexport C_word C_fcall C_s_a_u_i_integer_minus(C_word **ptr, C_word n, C_wor C_fctexport C_word C_fcall C_s_a_i_plus(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; C_fctexport C_word C_fcall C_s_a_u_i_integer_plus(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; C_fctexport C_word C_fcall C_s_a_u_i_integer_gcd(C_word **ptr, C_word n, C_word x, C_word y) C_regparm; +C_fctexport C_word C_fcall C_s_a_u_i_bignum_extract_digits(C_word **ptr, C_word n, C_word x, C_word start, C_word end) C_regparm; C_fctexport C_word C_fcall C_i_foreign_char_argumentp(C_word x) C_regparm; diff --git a/library.scm b/library.scm index 3651ebdb..4bdbde1c 100644 --- a/library.scm +++ b/library.scm @@ -38,7 +38,7 @@ maximal-string-length find-ratio-between find-ratio make-complex flonum->ratnum ratnum rat+/- +maximum-allowed-exponent+ mantexp->dbl ldexp round-quotient - ##sys#string->compnum ##sys#bignum-extract-digits ##sys#internal-gcd) + ##sys#string->compnum ##sys#internal-gcd) (not inline ##sys#user-read-hook ##sys#error-hook ##sys#signal-hook ##sys#schedule ##sys#default-read-info-hook ##sys#infix-list-hook ##sys#sharp-number-hook ##sys#user-print-hook ##sys#user-interrupt-hook ##sys#step-hook) @@ -1129,8 +1129,8 @@ EOF (##sys#*-2 x (##sys#slot args 0))) ) ) ) ) ) ) (define-inline (%bignum-digit-count b) (##core#inline "C_u_i_bignum_size" b)) -(define ##sys#bignum-extract-digits - (##core#primitive "C_u_bignum_extract_digits")) +(define-inline (##sys#bignum-extract-digits big start end) + (##core#inline_allocate ("C_s_a_u_i_bignum_extract_digits" 6) big start end)) ;; Karatsuba multiplication: invoked from C when the two numbers are ;; large enough to make it worthwhile. Complexity is O(n^log2(3)), diff --git a/runtime.c b/runtime.c index 614ded56..3068a64d 100644 --- a/runtime.c +++ b/runtime.c @@ -512,7 +512,6 @@ static WEAK_TABLE_ENTRY *C_fcall lookup_weak_table_entry(C_word item, C_word con static C_ccall void values_continuation(C_word c, C_word closure, C_word dummy, ...) C_noret; static C_word add_symbol(C_word **ptr, C_word key, C_word string, C_SYMBOL_TABLE *stable); static C_regparm int C_fcall C_in_new_heapp(C_word x); -static void bignum_actual_extraction(C_word c, C_word self, C_word result) C_noret; static void bignum_bitwise_and_2(C_word c, C_word self, C_word result) C_noret; static void bignum_bitwise_ior_2(C_word c, C_word self, C_word result) C_noret; static void bignum_bitwise_xor_2(C_word c, C_word self, C_word result) C_noret; @@ -5916,14 +5915,14 @@ C_regparm C_word C_fcall C_i_integer_length(C_word x) /* This is currently only used by Karatsuba multiplication and * Burnikel-Ziegler division. It is not intended as a public API! */ -void C_ccall -C_u_bignum_extract_digits(C_word c, C_word self, C_word k, C_word x, C_word start, C_word end) +C_regparm C_word C_fcall +C_s_a_u_i_bignum_extract_digits(C_word **ptr, C_word n, C_word x, C_word start, C_word end) { if (x & C_FIXNUM_BIT) { /* Needed? */ if (C_unfix(start) == 0 && (end == C_SCHEME_FALSE || C_unfix(end) > 0)) - C_kontinue(k, x); + return x; else - C_kontinue(k, C_fix(0)); + return C_fix(0); } else { C_word negp, size; @@ -5938,32 +5937,21 @@ C_u_bignum_extract_digits(C_word c, C_word self, C_word k, C_word x, C_word star size = end - start; if (size == 0 || start >= C_bignum_size(x)) { - C_kontinue(k, C_fix(0)); + return C_fix(0); } else { - C_word k2, kab[C_SIZEOF_CLOSURE(5)], *ka = kab; - k2 = C_closure(&ka, 5, (C_word)bignum_actual_extraction, - k, x, C_fix(start), C_fix(end)); - C_allocate_bignum(5, (C_word)NULL, k2, C_fix(size), negp, C_SCHEME_FALSE); + C_uword res, *res_digits, *x_digits; + res = C_allocate_scratch_bignum(ptr, C_fix(size), negp, C_SCHEME_FALSE); + res_digits = C_bignum_digits(res); + x_digits = C_bignum_digits(x); + /* Can't use bignum_digits_destructive_copy because that assumes + * target is at least as big as source. + */ + C_memcpy(res_digits, x_digits + start, C_wordstobytes(end - start)); + return C_bignum_simplify(res); } } } -static void bignum_actual_extraction(C_word c, C_word self, C_word result) -{ - C_word k = C_block_item(self, 1), - x = C_block_item(self, 2), - start = C_unfix(C_block_item(self, 3)), - end = C_unfix(C_block_item(self, 4)); - C_uword *result_digits = C_bignum_digits(result), - *x_digits = C_bignum_digits(x); - - /* Can't use bignum_digits_destructive_copy because that assumes - * target is at least as big as source. - */ - C_memcpy(result_digits, x_digits + start, C_wordstobytes(end-start)); - C_kontinue(k, C_bignum_simplify(result)); -} - /* This returns a tmp bignum negated copy of X (must be freed!) when * the number is negative, or #f if it doesn't need to be negated. * The size can be larger or smaller than X (it may be 1-padded).Trap