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] Make gas metering conditional #15901

Open
wants to merge 2 commits into
base: george/replay-benchmark-overrides
Choose a base branch
from

Conversation

georgemitenkov
Copy link
Contributor

@georgemitenkov georgemitenkov commented Feb 6, 2025

Description

  • Added UnmeteredGasAlgebra and AptosUnmeteredGasMeter. We have UnmeteredGasMeter defined in Move repository, but that one has no access to algebra, so using this seems better.
  • Added conditional flag to enable/disable gas metering. This is protected by a cargo feature ("benchmark") + defaults to true, so there should be no overhead or danger for prod builds, and benchmarking should be representative enough.
  • Finally, added an option to disable gas metering for replay benchmarking. This should help us understand performance better for historical workloads.

How Has This Been Tested?

Manual

Key Areas to Review

Checked unmetered meter is not used in prod.

Type of Change

  • New feature

Which Components or Systems Does This Change Impact?

  • Move/Aptos Virtual Machine
  • Developer Infrastructure

Checklist

  • I have read and followed the CONTRIBUTING doc
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I identified and added all stakeholders and component owners affected by this change as reviewers
  • I tested both happy and unhappy path of the functionality
  • I have made corresponding changes to the documentation

Copy link

trunk-io bot commented Feb 6, 2025

⏱️ 10m total CI duration on this PR
Job Cumulative Duration Recent Runs
check-dynamic-deps 4m 🟩🟩
rust-cargo-deny 4m 🟩🟩
general-lints 53s 🟩🟩
semgrep/ci 46s 🟩🟩
file_change_determinator 25s 🟩🟩
permission-check 5s 🟩🟩
permission-check 5s 🟩🟩
check-branch-prefix 1s 🟩

settingsfeedbackdocs ⋅ learn more about trunk.io

Copy link
Contributor Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@@ -7,7 +7,11 @@
mod algebra;
mod meter;
mod traits;
#[cfg(feature = "benchmark")]
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: we have a few places where we use the "bench" feature already, shall we follow the "convention"?

Comment on lines +484 to +501
static METER_GAS: OnceCell<bool> = OnceCell::new();

/// If benchmarking, conditionally enable unmetered or metered executions.
pub fn enable_gas_metering(enable: bool) {
if cfg!(feature = "benchmark") {
METER_GAS.set(enable).ok();
}
}

/// Returns whether the gas needs to be metered. When benchmarking, it is possible to configure it
/// to be turned off.
pub fn is_gas_metering_enabled() -> bool {
if cfg!(feature = "benchmark") {
METER_GAS.get().cloned().unwrap_or(true)
} else {
true
}
}
Copy link
Contributor

@vgao1996 vgao1996 Feb 6, 2025

Choose a reason for hiding this comment

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

Agreed that the pattern here offers some protection, but I still feel like this is quite hacky

  • Cargo feature flags, by their design, are additive -- if any crate in your dependency tree has a flag enabled then it is enabled for the whole tree. Based on this I find it troublesome we try to use it to gate more stuff.
  • I get that METER_GAS can only set once, but still, it being a global variable breaks a convenient property of (most) Rust code -- the ability to understand side effects with only knowledge from the current scope.
    • One previous example is the warm VM cache -- I once spent hours debugging the VM, trying to figure out why code didn't result in the changes I expected.
    • I fear that if we add more global switches to the VM it will be harder and harder to understand and control the VM behavior.

Is it possible to pass this flag in as a regular parameter? This way we let each call site control how gas should be configured.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree! Tried to encapsulate, but the issue is that otherwise I need to pass meter_enabled: bool config somewhere all the way from block executor. It can be part of config, but this seems irrelevant. Do you think it is better to pass a flag all the way to single transaction?

One other thing I was trying to do is that feature ensures at compile time this is a noop, so prod performance is not impacted in any way (thogh maybe difference is marginal?)

Re global - we already do this for paranoid checks, and this is not as bad as the warm cache, but 100% agree.

Let me try the paramter, and see how easy/ugly it gets so we can compare and find the best option👍

let vm_output = discarded_output(vm_status.status_code());
(vm_status, vm_output)
},
if cfg!(feature = "benchmark") && !is_gas_metering_enabled() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm generally a bit concerned whether we could have some misconfiguration and causes this feature to go public. I would suggest at least in the node initialization logic check that the gas is indeed enabled with benchmark flag set to false in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

+1, hence I used cargo feature here. Good point about the node config, do you have a code pointer?

I think we can also check if !cfg!(feature = "benchmark") is always metered for extra safety.

Copy link
Contributor

Choose a reason for hiding this comment

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

aptos_vm::natives::assert_no_test_natives(ERROR_MSG_BAD_FEATURE_FLAGS);

I believe victor also had a similar check here.

Copy link
Contributor

@runtian-zhou runtian-zhou left a comment

Choose a reason for hiding this comment

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

Stamp to unblock

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants