Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

ethcore: minor optimization of modexp by using LR exponentiation #9697

Merged
merged 1 commit into from
Oct 4, 2018

Conversation

andresilva
Copy link
Contributor

Optimize modexp implementation by doing left-to-right binary exponentiation to keep multiplicands lower. The implementation can be further optimised by using a bigger limb size for the BigUint currently num is using u32.

benchcmp:

 name                          modexp_base ns/iter  modexp_final ns/iter  diff ns/iter   diff %  speedup
 modexp_eip_example1           501,834              304,093                   -197,741  -39.40%   x 1.65
 modexp_eip_example2           267                  200                            -67  -25.09%   x 1.33
 modexp_nagydani_1_pow0x10001  38,693               38,748                          55    0.14%   x 1.00
 modexp_nagydani_1_qube        7,477                6,087                       -1,390  -18.59%   x 1.23
 modexp_nagydani_1_square      5,180                3,528                       -1,652  -31.89%   x 1.47
 modexp_nagydani_2_pow0x10001  82,100               82,079                         -21   -0.03%   x 1.00
 modexp_nagydani_2_qube        14,532               10,895                      -3,637  -25.03%   x 1.33
 modexp_nagydani_2_square      10,033               6,095                       -3,938  -39.25%   x 1.65
 modexp_nagydani_3_pow0x10001  251,002              242,514                     -8,488   -3.38%   x 1.04
 modexp_nagydani_3_qube        43,365               30,771                     -12,594  -29.04%   x 1.41
 modexp_nagydani_3_square      29,139               16,189                     -12,950  -44.44%   x 1.80
 modexp_nagydani_4_pow0x10001  825,013              772,208                    -52,805   -6.40%   x 1.07
 modexp_nagydani_4_qube        137,210              94,985                     -42,225  -30.77%   x 1.44
 modexp_nagydani_4_square      92,899               47,773                     -45,126  -48.58%   x 1.94
 modexp_nagydani_5_pow0x10001  2,930,324            2,760,226                 -170,098   -5.80%   x 1.06
 modexp_nagydani_5_qube        493,096              330,857                   -162,239  -32.90%   x 1.49
 modexp_nagydani_5_square      330,625              166,783                   -163,842  -49.56%   x 1.98

@andresilva andresilva added A0-pleasereview 🤓 Pull request needs code review. M4-core ⛓ Core client code / Rust. labels Oct 3, 2018
@dvdplm
Copy link
Collaborator

dvdplm commented Oct 3, 2018

Copy link
Collaborator

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm. Nice speedup!

Can't help wondering if SIMD could be brought to bear on this – did you look into that? :)

@andresilva
Copy link
Contributor Author

I think if the num library starts using u64 for its "words" and u128 for "double words", LLVM will generate better code for the primitive operations like mul and mod, that will probably give a 2x speedup. I wouldn't know how to vectorize this code though 😅. I also implemented the LR k-ary algorithm (14.83) where you process more than one bit of the exponent at a time. But it wasn't worth it, probably only pays off for really big exponents (since you have to precompute a table).

@debris debris added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Oct 4, 2018
@debris debris merged commit 726884a into master Oct 4, 2018
@debris debris deleted the andre/optimize-modexp branch October 4, 2018 11:29
dvdplm added a commit that referenced this pull request Oct 9, 2018
…mon-deps

* origin/master:
  fix (light/provider) : Make `read_only executions` read-only (#9591)
  ethcore: fix detection of major import (#9552)
  return 0 on error (#9705)
  ethcore: delay ropsten hardfork (#9704)
  make instantSeal engine backwards compatible, closes #9696 (#9700)
  Implement CREATE2 gas changes and fix some potential overflowing (#9694)
  Don't hash the init_code of CREATE. (#9688)
  ethcore: minor optimization of modexp by using LR exponentiation (#9697)
  removed redundant clone before each block import (#9683)
@5chdn 5chdn added this to the 2.2 milestone Oct 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants