Skip to content
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

Optimization possibility of memory usage for loops #9046

Open
daejunpark opened this issue May 27, 2020 · 3 comments
Open

Optimization possibility of memory usage for loops #9046

daejunpark opened this issue May 27, 2020 · 3 comments
Labels
epic effort Multi-stage task that may require coordination between team members across multiple PRs. high impact Changes are very prominent and affect users or the project in a major way. needs design The proposal is too vague to be implemented right away optimizer selected for development It's on our short-term development

Comments

@daejunpark
Copy link

[This issue has been discussed with @axic, and reported here to be tracked and further discussed.]

Description

In the current code generation (even with the optimization enabled with the flags --optimize --optimize-runs 5000000), there is still room for improvement of the memory usage for loops.

Specifically, if we have sha256(abi.encodePacked(arg1, arg2)) in a loop, every iteration consumes new memory entries to store the arguments arg1 and arg2, even if the same memory entries can be reused over the whole iterations.

For example, for this loop, the first iteration consumes the following entries to store the arguments:

memory[128:159] := 64 // the size of arguments
memory[160:191] := <the-first-argument>
memory[192:223] := <the-second-argument>

and then the second iteration consumes the following:

memory[224:255] := 64 // the size of arguments
memory[256:287] := <the-first-argument>
memory[288:319] := <the-second-argument>

and so on.

In the end, the total 3072 (= 32 iterations * 96 bytes per iteration) bytes of memory are consumed to compute the sha256 function, while the optimized behavior would consume only the 96 bytes for the whole iterations. This ended up wasting ~300 gas unit.

Environment

  • Compiler version: 0.6.8+commit.0bbfe453.Linux.g++
  • Command line flags: --optimize --optimize-runs 5000000

Steps to Reproduce

Compile https://github.com/axic/eth2-deposit-contract/blob/r1/deposit_contract.sol with the following command line flags:

$ solc deposit_contract.sol --asm --optimize --optimize-runs 5000000

Then see the generated assembly code for the aforementioned loop (i.e., code blocks between tag_123 and tag_124).

(I'll provide a minimal example later.)

@chriseth
Copy link
Contributor

Note that neither the copmpiler nor optimizer does any lifetime tracking of memory objects. abi.encodePacked returns a memory object and thus could be used further down the road, so lifetime tracking is required here if we do not just want to optimize for a special case. There are proposals to do lifetime tracking in the yul optimizer, though.

@chriseth
Copy link
Contributor

chriseth commented Jun 3, 2020

Relates to #5107

@axic
Copy link
Member

axic commented Feb 10, 2021

Just like we have a codegen shortcut for assigning hashes to constants (#4024) and address.code.length (#10778), we could have a similar shortcut for the keccak256(abi.encode*..) and keccak256(bytes.concat..) (see #10903) cases.

We may want to be a bit reserved though, as this will incentivise this pattern, and I think we should add this shortcut if we believe in the long term we can have this done efficiently even without the shortcut.

@cameel cameel added selected for development It's on our short-term development epic effort Multi-stage task that may require coordination between team members across multiple PRs. high impact Changes are very prominent and affect users or the project in a major way. needs design The proposal is too vague to be implemented right away labels Sep 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
epic effort Multi-stage task that may require coordination between team members across multiple PRs. high impact Changes are very prominent and affect users or the project in a major way. needs design The proposal is too vague to be implemented right away optimizer selected for development It's on our short-term development
Projects
None yet
Development

No branches or pull requests

5 participants