-
Notifications
You must be signed in to change notification settings - Fork 203
No grow necessary in mp_set_int* functions #221
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
Conversation
Most allocators also don't return less than 16 bytes. |
thou shalt then never call |
mp_shrink should never shrink below this minimum precision? This should also be included here. |
I'd say it should be enough to never shrink below the required storage for a |
they're always allocated Edit: btw I've killed the build as this requires more changes |
Yeah, I found mp_shrink() as well ;-( So mp_shrink() should be modified to always shrink to at least MP_PREC, and also always a multiple of that. And .. mp_init_size/mp_grow lied: The comment said they always allocote MP_PREC digits extra, but in fact they always allocate MP_PREC+1 digits extra. That's too much. Fixed that as well .... |
not MP_PREC |
156ab13
to
709b708
Compare
Hoping it's better now! |
can you please fix the commit message? |
bn_mp_shrink.c
Outdated
@@ -7,20 +7,21 @@ | |||
int mp_shrink(mp_int *a) | |||
{ | |||
mp_digit *tmp; | |||
int used = 1; | |||
int alloc = MP_PREC; |
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.
this still shrink's only down to MP_PREC
and not the required storage for a long long
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.
I think the requirement of MP_PREC should be that it can store at least a long long. That's what the change in tommath.h was meant for! mp_init() also starts with allocating MP_PREC digits.
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.
So, for MP_8BIT, the minimum MP_PREC=16, for MP_16BIT, the minimum MP_PREC=8, for MP_32BIT the minimum MP_PREC=4, for MP_64BIT it is MP_PREC=2. That should be documented somewhere.
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.
@czurnieden what do you say?
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.
What about adding a MP_MIN_PREC setting to the minimums given by @nijtmans and changing MP_PREC such that it is always larger than MP_MIN_PREC?
Furthermore I think MP_PREC is usually too large. But this depends heavly on the use case. Via static_assert it could be checked that the condition always holds if MP_PREC is set by the user.
Maybe just set MP_MIN_PREC to 16 / sizeof (mp_digit)?
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.
How about an assert somewhere in the code checking that MP_PREC * sizeof(mp_digit) >= sizeof(long long) ???
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.
Hm... I meant MP_PREC * DIGIT_BIT >= sizeof(long long). That means that MP_PREC for MP_8BIT could even be as low as 10, although that's not a power of 2.
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.
Hm .... MP_PREC * DIGIT_BIT >= CHAR_BIT * sizeof(long long)
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.
How about an assert somewhere in the code checking that MP_PREC * sizeof(mp_digit) >= sizeof(long long) ???
no we need to make it sure at compile time
I'd make it #define MP_MIN_PREC ((CHAR_BIT * sizeof(long long))/DIGIT_BIT)
and hope that nobody uses this macro in a #if
preprocessor statement :)
and please keep the patch to to tommath.h regarding MP_8BIT
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.
czurnieden what do you say?
A MP_PREC
that is always of the same bitsize no matter what the MP_xBIT
is would add nicely to the "rounding edges" part of the LTM update, yes.
709b708
to
b83b6b9
Compare
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.
(pressed the wrong button again *grr*)
As hinted at in my other comment: if you find a way that MP_PREC
/MP_MIN_PREC
is of the same size , independent of MP_xBIT
I would welcome this patch.
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.
I am generally very positive about these changes. It is much better if there are some reasonable guarantees of minimal int sizes. However I would like to see these extra size gone, to ensure all memory allocations reserve exactly what they need. This will expand the scope of this PR a bit, but it is worth it I think.
So, here my new attempt. MP_MIN_PREC is a multiple of MP_PREC such that at least a long long fits. So, we can set MP_PREC to 2, or even 1 if desired. All allocations will be a multiple of MP_PREC mp_digit's. |
Yes, looks good! |
@nijtmans @czurnieden What is the status here? |
Well, I'm on vacation, so I can't do anything now. I'll have a look when I'm back |
@nijtmans Ok 👍 |
close this in favor of #253 |
In the mp_set_long_long (and related functions), an mp_grow() call is done, but that's only necessary if the already allocated room (MP_PREC) is so small that not even 64 bits fit. There is only one such a situation: -DMP_LOW_MEM in combination with -DMP_8BIT.
Therefore, I propose to increase the minimum MP_PREC from 8 to 16 in this case (allocating 8 bytes is ridicilously small anyway), then the mp_grow() is no longer necessesary in any mode.
This means that the minimum number of bytes allocated are always minimum 16, which is always sufficient to store the 64 bits of a long long.