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

Benchmark all functions receiving "special treatment" in FunC compiler against related TVM instructions #1564

Open
novusnota opened this issue Jan 24, 2025 · 2 comments
Assignees
Labels
kind: gas! Gas consumption and fee-related things scope: stdlib The Tact standard library (src/stdlib)
Milestone

Comments

@novusnota
Copy link
Member

novusnota commented Jan 24, 2025

For example, compare the gas usage of .load_int() in FunC or .loadInt() in Tact to an assembly function that'll use just LDIX. Do so for all functions that are marked with // special treatment in Func compiler, so not replaced with X.

Alongside those gas benchmarks, it might be nice to gather sequences of instructions executed from the Sandbox logs.

This might help with:

  1. Discovering new optimizations to perform
  2. Replacing FunC functions with asm functions iff we can match or outmatch them
@novusnota novusnota added kind: gas! Gas consumption and fee-related things scope: stdlib The Tact standard library (src/stdlib) labels Jan 24, 2025
@novusnota novusnota added this to the v1.6.0 milestone Jan 24, 2025
@novusnota
Copy link
Member Author

Related to #1554

@novusnota novusnota changed the title Benchmark all functions receiving "special treatment" in FunC compiler against using related TVM instructions Benchmark all functions receiving "special treatment" in FunC compiler against related TVM instructions Jan 24, 2025
@Shvandre
Copy link
Contributor

Shvandre commented Jan 27, 2025

I did some research on this topic and found a few interesting details:

  1. The funC compiler has an optimization where, if the second argument in store is constant, it uses the STU/STI instructions instead of STX/STIX. This saves one instruction for pushing the argument onto the stack – around 18/26 gas.
  2. Storing arguments in a straightforward order is often more gas-efficient than storing them across multiple lines.

For example first function is better, than the second one.

builder usualBuild() impure inline {
    builder b = begin_cell().store_uint(0, 32).store_int(1, 32);
    return b;
}

builder usualBuild2() impure inline {
    builder b = begin_cell();
    b = b.store_uint(0, 32);
    b = b.store_int(1, 32);
    return b;
}

(In this case, there are extra SWAP instructions.)

  1. If we remove the STU/STI optimization and use STUX/STIX instead, we get an additional PUSH, which typically costs 26 or 34 gas, depending on the value.

In conclusion, I’d recommend not removing this optimization that funC already provides. Instead, I’d focus on optimizing these instructions further, like turning them into something like STSLICECONST #1592 , STZEROES, or STONES, which is #1561

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: gas! Gas consumption and fee-related things scope: stdlib The Tact standard library (src/stdlib)
Projects
None yet
Development

No branches or pull requests

3 participants