You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
25: do not convert carry/borrow to/from DoubleBigDigit r=cuviper a=tspiteri
Currently `adc`, `sbb`, `mac_with_carry` and `mul_with_carry` in *algorithms.rs* take the carry/borrow as a `BigDigit`, then convert it every iteration to `DoubleBigDigit` for the addition/subtraction. With this commit, a kind of accumulator takes place of the carry and borrow. It is stored as a `DoubleBigDigit` and not converted to/from `BigDigit` at all. For subtraction, the accumulator is stored as a `SignedDoubleBigDigit` in order to enable arithmetic right shift and to be able to easily handle subtraction.
I'm not very familiar with the crate's benchmarking methods. I wrote some hacky benchmarks for a quick comparison. Basically, just have two vectors `[10000000, 0, !0, 1, 29999999]` and `[10, !0, 5, 234, 23]`, and add/subtract/multiply a couple hundred times. I saw these gains:
```
running 6 tests
test tests::bench_changed_add ... bench: 992 ns/iter (+/- 58)
test tests::bench_changed_mul ... bench: 9,667 ns/iter (+/- 185)
test tests::bench_changed_sub ... bench: 1,497 ns/iter (+/- 38)
test tests::bench_original_add ... bench: 1,085 ns/iter (+/- 50)
test tests::bench_original_mul ... bench: 9,838 ns/iter (+/- 284)
test tests::bench_original_sub ... bench: 1,642 ns/iter (+/- 14)
```
The gains are not very large, after all only a couple of assembly instructions per iteration are saved. I also do not know whether other architectures than x86_64 are affected similarly or in the opposite direction.
The change in the parameter from `&mut BigDigit` to `&mut DoubleBigDigit` is automatically handled in other files, as carry is simply initialized as zero and compared to zero at the end, with the type being inferred.
0 commit comments