Skip to content

Div by zero#31

Merged
nlordell merged 5 commits into
nlordell:mainfrom
NCGThompson:div-by-zero
Apr 16, 2025
Merged

Div by zero#31
nlordell merged 5 commits into
nlordell:mainfrom
NCGThompson:div-by-zero

Conversation

@NCGThompson

Copy link
Copy Markdown
Contributor

Made some minor optimizations to udivmod4. Speed is not noticeably improved, but panic statements may be more helpful and binaries may be smaller.

@NCGThompson

Copy link
Copy Markdown
Contributor Author

Previously, if the high() of both operands were zero and the rem return was set to Some, then each of the remainder and the quotient were calculated separately without any optimizations. % gives a different zero divisor message than /. Now, the function will only panic with /'s message, and the remainder is derived from the quotient. Note that even if udivmod4()'s caller checks for zero, the compiler likely won't eliminate the redundancy.

div_mod_knuth() expects the high high() of the denominator to be non-zero, and that holds true when called by udivmod4(), While div_mod_knuth() is public, its only caller in the library is udivmod4(). Despite being inlined, there were still some redundant checks when called through the function. When called directly, it relied on debug_asserts to validate the input. Now, the input is checked with a regular assert that has a custom error message. Because the input is always checked, we can safely put compiler hints further down, eliminating the redundant checks. The assert statement is elided when inlined in udivmod4(), leaving no redundant checks.

Results may vary depending on compiler settings and targets.

@NCGThompson NCGThompson marked this pull request as draft October 28, 2023 04:26
@NCGThompson

Copy link
Copy Markdown
Contributor Author

Converted to draft so I can add docs to Knuth.

@NCGThompson NCGThompson marked this pull request as ready for review October 29, 2023 02:55
Comment thread src/intrinsics/native/divmod.rs
@NCGThompson NCGThompson marked this pull request as draft October 29, 2023 20:55
NCGThompson and others added 2 commits October 29, 2023 17:05
Co-authored-by: Nicholas Rodrigues Lordello <n@lordello.net>
@NCGThompson

Copy link
Copy Markdown
Contributor Author

udivmod4 usually isn't inlined, but it is always behind a safe wrapper. If we really wanted to optimize the binary size, we could make its abort rather than unwrapping, or even mark the intrinsics as unsafe and like I did to div_mod_knuth. It probably doesn't make a big difference though.

@NCGThompson NCGThompson marked this pull request as ready for review October 30, 2023 04:31
@nlordell

nlordell commented Nov 4, 2023

Copy link
Copy Markdown
Owner

Hey, sorry I haven't had time to look at this yet. Will get around to reviewing it either this weekend or early next week.

@NCGThompson

Copy link
Copy Markdown
Contributor Author

As it turns out, making the division function infallible can make a big difference iff the actual result of the division is unneeded. However, in that case, it sounds reasonable to put the responsibility on the programmer to remove the useless 256-bit division call.

@nlordell

Copy link
Copy Markdown
Owner

This is great. Will run the fuzzer on this to make sure nothing broke, then will merge.

@wdanilo

wdanilo commented Apr 14, 2025

Copy link
Copy Markdown

Is this lib still alive?

@nlordell

Copy link
Copy Markdown
Owner

It is (as in, I still use it), but https://github.com/recmo/uint is definitely in wider use and more actively maintained.

I still need to run the fuzzer for this PR 🙈 - and haven't done so mostly because these performance optimizations aren't that useful for my usecase.

@nlordell nlordell merged commit ddb521c into nlordell:main Apr 16, 2025
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.

3 participants