-
Notifications
You must be signed in to change notification settings - Fork 45
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
Division / Modulo scale poorly. #46
Comments
Is this because we first shift left the divisor? |
This is because sometimes where clauses scale exponentially. Other operators (I think multiplication at least) had similar issues, but I was able to find a way to structure them so as to get linear where-clause scaling. I have not found a way to structure division for that. The division algorithm is fine. |
This reddit post contains a workaround that may be useful here. |
So far, the workaround in that post seems to not help here: |
On recent builds, at least 1.12.0-nightly (2ad5ed07f 2016-07-08), this is much better (although still linear): http://i.imgur.com/oZt8JlH.png Note: the old and new here are not comparing compiler versions, but typenum versions. This chart should be compared to the previous one. |
I'm playing with this, on the http://i.imgur.com/a8Jb7i3.png It does fix dimensioned issue 22 though, so I guess I'll play with it more and see if I can make it faster. |
I just found out about this, which looks very interesting and may eventually fix this issue for us. |
Another approach might be to use a more efficient algorithm to compute the division. I would be willing to experiment with implementing it, but I would need some guidance. |
@ranma42 I've skimmed through it, and it looks interesting. I'd be happy to help with any guidance you need. Note that typenum's unsigned integers are variable precision, so we don't have to worry about keeping everying in e.g. 32 bits as they do. Also, our signed integers are not two's complement, but are just unsigned integers with a sign flag, so it's enough to implement just for unsigned integers. The current division algorithm starts at line 1121 of uint.rs, and may give some idea of how to translate an algorithm to Rust's type system, but I'd be happy to help with any specifics. |
I started working on it :) I started implementing the reciprocal at a type level here ranma42@c1a9674 , but even with just 6 iterations the compiler gets very slow. Am I doing something wrong? |
I've finally had a chance to look at. I don't see anything that stands out, but I also don't really understand the algorithm. It seemed like there were a few different versions in the paper you linked; if you could relate the exact algorithm you're using, I could at least provide a set of eyes to check that the implementation matches the algorithm. As far as tracing/debugging what's happening, I don't have any great approaches. When things have blown up on me, I've just refactored until I get something that works. It's not a great method, but I don't know of any others without taking a deep dive into Rust's type-system code. |
This is the implementation I used for my experiments, based on "Figure 5: UNR recurrence method" in the aforementioned paper. The main differences are:
My tentative implementation of reciprocal approximation at type level is supposed to be a straightforward translation of the |
This appears fixed in the latest nightly: https://i.imgur.com/xWee44h.png Thanks to @llogiq for pointing out this reddit post to me. |
Due to an exponentially scaling issue, these operations seem to scale linearly (instead of logrithmically).
We should try to fix this at some point, or at least pay attention to it if Rust improvements fix it for us.
The text was updated successfully, but these errors were encountered: