Skip to content

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

Closed
wants to merge 4 commits into from

Conversation

nijtmans
Copy link
Collaborator

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.

@minad
Copy link
Member

minad commented Apr 12, 2019

Most allocators also don't return less than 16 bytes.

@sjaeckel
Copy link
Member

thou shalt then never call mp_shrink before that :)

@minad
Copy link
Member

minad commented Apr 12, 2019

mp_shrink should never shrink below this minimum precision? This should also be included here.
@sjaeckel Can it happen that numbers are completely empty or are they always allocated?

@sjaeckel
Copy link
Member

sjaeckel commented Apr 12, 2019

I'd say it should be enough to never shrink below the required storage for a long long then! otherwise the target of mp_shrink isn't fulfilled anymore

@sjaeckel
Copy link
Member

sjaeckel commented Apr 12, 2019

@sjaeckel Can it happen that numbers are completely empty or are they always allocated?

they're always allocated

Edit: btw I've killed the build as this requires more changes

@nijtmans
Copy link
Collaborator Author

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 ....

@sjaeckel
Copy link
Member

So mp_shrink() should be modified to always shrink to at least MP_PREC, and also always a multiple of that.

I'd say it should be enough to never shrink below the required storage for a long long then

not MP_PREC

@nijtmans nijtmans force-pushed the no_grow_in_set_int branch from 156ab13 to 709b708 Compare April 12, 2019 14:32
@nijtmans
Copy link
Collaborator Author

Hoping it's better now!

@nijtmans nijtmans requested review from minad and sjaeckel April 12, 2019 14:34
@sjaeckel
Copy link
Member

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;
Copy link
Member

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

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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.

Copy link
Member

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?

Copy link
Member

@minad minad Apr 12, 2019

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)?

Copy link
Collaborator Author

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) ???

Copy link
Collaborator Author

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.

Copy link
Collaborator Author

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)

Copy link
Member

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

Copy link
Contributor

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_xBITis would add nicely to the "rounding edges" part of the LTM update, yes.

@nijtmans nijtmans force-pushed the no_grow_in_set_int branch from 709b708 to b83b6b9 Compare April 12, 2019 14:55
@nijtmans nijtmans requested a review from czurnieden April 12, 2019 15:12
Copy link
Contributor

@czurnieden czurnieden left a 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.

Copy link
Member

@minad minad left a 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.

@nijtmans
Copy link
Collaborator Author

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.

@czurnieden
Copy link
Contributor

Yes, looks good!
But be aware that MP_PREC can be changed by the user and I think it would be helpful if the size of MP_PREC is checked. The preprocessor can do it and utter a #warning if e.g.: MP_PREC < 1. Typos are easily made and if it is equally easy to check them it should be done.

This was referenced Apr 16, 2019
@minad
Copy link
Member

minad commented Apr 27, 2019

@nijtmans @czurnieden What is the status here?

@nijtmans
Copy link
Collaborator Author

Well, I'm on vacation, so I can't do anything now. I'll have a look when I'm back

@minad
Copy link
Member

minad commented Apr 27, 2019

@nijtmans Ok 👍

@minad minad mentioned this pull request May 8, 2019
This was referenced May 10, 2019
@minad
Copy link
Member

minad commented May 12, 2019

close this in favor of #253

@minad minad closed this May 12, 2019
@nijtmans nijtmans deleted the no_grow_in_set_int branch July 5, 2019 23:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants