-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Addition of fast division (recursive divrem only) #370
Conversation
626b5d5
to
37ba298
Compare
Should this change anything about my in-progress implementation of the faster to_radix? |
No. |
b9d6e5a
to
ff6759a
Compare
I would like to have this 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you refactor this a bit, introducing a s_mp_div_small function? Then disabling s_mp_div_recursive/school would result in the small function being used.
if (MP_HAS(S_MP_DIV_RECURSIVE)
&& (b->used > MP_KARATSUBA_MUL_CUTOFF)
&& (b->used <= ((a->used)/3*2))) {
err = s_mp_div_recursive(a, b, c, d);
} else if (MP_HAS(S_MP_DIV_SCHOOL)) {
err = s_mp_div_school(a, b, c, d);
} else {
err = s_mp_div_small(a, b, c, d);
}
It seems BN_MP_DIV_SMALL is the only macro we have which enables an alternative version being built, circumventing the MP_HAS configuration system.
Yepp, no prob'.
As we are working towards 2.0.0 now (Ignoring the bugfix-versions 1.2.x): we could change it and include it in the |
ff6759a
to
260b037
Compare
The snippet if (MP_HAS(S_MP_DIV_RECURSIVE)
&& (b->used > MP_KARATSUBA_MUL_CUTOFF)
&& (b->used <= ((a->used)/3*2))) {
err = s_mp_div_recursive(a, b, c, d);
} else if (MP_HAS(S_MP_DIV_SCHOOL)) {
err = s_mp_div_school(a, b, c, d);
} else {
err = s_mp_div_small(a, b, c, d);
} Does not seem to work as intended (with |
What do you mean - does not work as intended? If you compile with LTM_NOTHING, only s_mp_div_small will be used as I see it. And yes, this is 2.0 - we can do breaking changes. |
Only if I remove the guards and that will compile The way our configuration system works now results in the following entry in `tommath_class.h #if defined(BN_MP_DIV_C)
# define BN_MP_CMP_MAG_C
# define BN_MP_COPY_C
# define BN_MP_ZERO_C
# define BN_S_MP_DIV_RECURSIVE_C
# define BN_S_MP_DIV_SCHOOL_C
# define BN_S_MP_DIV_SMALL_C
#endif So all three are defined and hence all three get compiled if I remove the guards. If I don't remove the guards, the functions are not included and the linker complains. If I add extra guards around the branching like e.g.: #ifndef BN_S_MP_DIV_SMALL
if (MP_HAS(S_MP_DIV_RECURSIVE)
&& (b->used > MP_KARATSUBA_MUL_CUTOFF)
&& (b->used <= ((a->used)/3*2))) {
err = s_mp_div_recursive(a, b, c, d);
} else {
err = s_mp_div_school(a, b, c, d);
}
#else
err = s_mp_div_small(a, b, c, d);
#endif it works but it looks ugly and defies the reason you introduced Any suggestions? |
Yes, we should rework the configuration system. Optional dependencies (guarded by MP_HAS) should not be required automatically in tommath_class.h. I made such suggestions already in #301. But this is independent of this PR and we can address this later. |
OK.
It is still on the TODO list, no worry. |
8a6ce73
to
929ef57
Compare
@czurnieden this PR seems almost ready. Can you rebase it? |
93d6283
to
ef00315
Compare
Bugfixes not withstanding, of course, but yes. |
demo/test.c
Outdated
@@ -2325,6 +2325,140 @@ static int test_mp_radix_size(void) | |||
return EXIT_FAILURE; | |||
} | |||
|
|||
#ifndef S_MP_DIV_SMALL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the guard and test both functions test_s_mp_div_recursive, trst_s_mp_div_small. Additional guards are rarely necessary. MP_HAS takes care of it.
@czurnieden please squash @sjaeckel this looks ready from my side |
I forgot - does it make sense to add an additional cut off here? Instead of using karatsuba? |
d0c38cf
to
a3b2386
Compare
" out-of-date with the base branch"?
Found no differences above Karatsuba only below (it needs fast multiplication to function). The larger difference is in the relation numerator/denominator where it stops being faster approaching ~2/3 and even starts to get slower above 0.8. I don't think that any kind of tuning would make sense. |
Hmm ok, but I mean is there a theoretical reason why the cutoff should be the same? If there is none, I would prefer if you introduce another constant (even if the value is the same). |
As I said: it needs fast multiplication to function and the lowest cutoff for that is the Karatsuba cutoff; there is a direct connection, not just coincidence. We can ignore Comba here because the most likely reason for not wanting the Comba algorithm is lack of memory which means there is no other fast multiplication in that case and I'm pretty sure no space for fast division either. |
Ok! |
a3b2386
to
9edd185
Compare
Direct implementation of algorithms 1.8 "RecursiveDivRem" and 1.9 "UnbalancedDivision"
from:
Brent, Richard P., and Paul Zimmermann. "Modern computer arithmetic"
Vol. 18. Cambridge University Press, 2010
Available online
pages 19ff. in the above online document