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

Bench for Move based transfer with Gas #190

Merged
merged 12 commits into from
Jan 19, 2022

Conversation

oxade
Copy link
Contributor

@oxade oxade commented Jan 16, 2022

Extending benchmark to measure Move based mass-transfers using the Gas module.
Now that we have two paths for executing transactions (Rust and Move), it's imperative that we measure the differences in performance.
This PR adds the option to exercise the Move transfer the same way we exercise the native Rust transfer.
It also incorporates module caching as this was a significant bottleneck in Adapter flow: [fastx adapter] Cache the VM to amortise module verification #192

Usage for move:
./bench --use-move {other args}
Without move (native Rust):
./bench {other args}

Results: Move vs Native (lower% is better)
Orders Only
38k vs 45k => 15.5%
Certs Only
19k vs 23k => 17%
Orders And Certs
12.5k vs 15k => 17%

@sblackshear
Copy link
Collaborator

We probably shouldn't use ObjectBasics for this because it is test code that will soon be moved out of the framework (this was finally unblocked by e51bc66).

Instead, I'd recommend adding a callable version of Coin::transfer (e.g.,

public fun transfer<T>(c: Coin<T>, recipient: vector<u8>, _ctx: TxContext) {
  Transfer::transfer(c, Address:new(recipient))
}

But I recall that @lxfind had some concerns about exposing this as an entrypoint--is that right Xun?

@oxade
Copy link
Contributor Author

oxade commented Jan 16, 2022

We probably shouldn't use ObjectBasics for this because it is test code that will soon be moved out of the framework (this was finally unblocked by e51bc66).

Instead, I'd recommend adding a callable version of Coin::transfer (e.g.,

public fun transfer<T>(c: Coin<T>, recipient: vector<u8>, _ctx: TxContext) {
  Transfer::transfer(c, Address:new(recipient))
}

But I recall that @lxfind had some concerns about exposing this as an entrypoint--is that right Xun?

Ah I did not know ObjectBasics was temporary. Will try Coin::transfer

@lxfind
Copy link
Contributor

lxfind commented Jan 16, 2022

Probably should add a new bench type for Move calls instead of adding use_move. I imagine we want to test the performance a few different primitives. Whether or not to enable move also doesn't matter much without the confirmation stage which does the execution.

As for transfer, I think adding a transfer function to Coin makes sense. I was more concerned exposing a generic transfer inside Transfer module.

@sblackshear
Copy link
Collaborator

As for transfer, I think adding a transfer function to Coin makes sense. I was more concerned exposing a generic transfer inside Transfer module.

Gotcha--sounds like we're on the same page!

@oxade
Copy link
Contributor Author

oxade commented Jan 16, 2022

Probably should add a new bench type for Move calls instead of adding use_move. I imagine we want to test the performance a few different primitives. Whether or not to enable move also doesn't matter much without the confirmation stage which does the execution.

As for transfer, I think adding a transfer function to Coin makes sense. I was more concerned exposing a generic transfer inside Transfer module.

You can specify whether to measure Order or Confirmation stages or both (default is both) with --benchmark-type
But yes overall I will define a more extensive benchmark for Move calls. This is the first step that's as similar to the existing Rust impl for quick comparisons

@oxade
Copy link
Contributor Author

oxade commented Jan 16, 2022

@lxfind
I actually noticed a considerable dip in performance during the Order stage with Move orders, so I reckon we keep monitoring it

@lxfind
Copy link
Contributor

lxfind commented Jan 16, 2022

@lxfind I actually noticed a considerable dip in performance during the Order stage with Move orders, so I reckon we keep monitoring it

Wow good catch!

@lxfind
Copy link
Contributor

lxfind commented Jan 16, 2022

I am guessing it's because we currently deserialize the modules to get the id. Easy win opportunity.

@oxade
Copy link
Contributor Author

oxade commented Jan 16, 2022

I am guessing it's because we currently deserialize the modules to get the id. Easy win opportunity.

Very likely. We should dig deeper

@gdanezis
Copy link
Collaborator

I am guessing it's because we currently deserialize the modules to get the id. Easy win opportunity.

Very likely. We should dig deeper

Yes, that is a very good catch -- we should not see such a dip at the order stage. However, my main target for optimisation is certs at this point.

@oxade oxade changed the title Bench for Move based transfer with ObjectBasics Bench for Move based transfer with Gas Jan 18, 2022
@oxade
Copy link
Contributor Author

oxade commented Jan 18, 2022

@sblackshear
When moving over to Gas (over ObjectBasics), I was not able to get any function to work that had a signature taking generics.
For example something like this would not work because the signature violates the rules in the adapter (regardless of if I specified the type args)

public fun transfer<T>(c: Coin<T>, recipient: vector<u8>, _ctx: TxContext) {
  Transfer::transfer(c, Address:new(recipient))
}

Function signature violation occurred here https://github.com/MystenLabs/fastnft/blob/main/fastx_programmability/adapter/src/adapter.rs#L368

So the current solution uses a wrapper in GAS.move. Let me know the better way to do this from Coin.move or with generics

Comment on lines 219 to 222
// Do I really need this TypeArg? Does not make a diff

//vec![move_core_types::language_storage::TypeTag::Struct(
//GasCoin::type_(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@sblackshear specifying type_args did not make a difference here so I committed them.
However I reckon they might be useful when calling a generic fn

Copy link
Collaborator

Choose a reason for hiding this comment

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

We will need them eventually, but punting on them until we use Coin::transfer seems reasonable.

@sblackshear
Copy link
Collaborator

@sblackshear When moving over to Gas (over ObjectBasics), I was not able to get any function to work that had a signature taking generics. For example something like this would not work because the signature violates the rules in the adapter (regardless of if I specified the type args)

public fun transfer<T>(c: Coin<T>, recipient: vector<u8>, _ctx: TxContext) {
  Transfer::transfer(c, Address:new(recipient))
}

Function signature violation occurred here https://github.com/MystenLabs/fastnft/blob/main/fastx_programmability/adapter/src/adapter.rs#L368

So the current solution uses a wrapper in GAS.move. Let me know the better way to do this from Coin.move or with generics

My bad... there were more issues with this than I anticipated. I dropped #200 which adds an adapter test to ensure that Move-powered transfers will actually work end-to-end + fixes all the problems you found.

@oxade
Copy link
Contributor Author

oxade commented Jan 18, 2022

https://github.com/MystenLabs/fastnft/blob/main/fastx_programmability/adapter/src/adapter.rs#L368

Thanks
I see you removed the function signature check
What was the reason for having it before?

ObjectID::random(),
SequenceNumber::new(),
keypair.0,
rand::thread_rng().gen_range(0..0xFFFFFF),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we use a seeded RNG here? Want to make sure we get the same values across different runs.

Comment on lines 219 to 222
// Do I really need this TypeArg? Does not make a diff

//vec![move_core_types::language_storage::TypeTag::Struct(
//GasCoin::type_(),
Copy link
Collaborator

Choose a reason for hiding this comment

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

We will need them eventually, but punting on them until we use Coin::transfer seems reasonable.

fastpay/src/bench.rs Outdated Show resolved Hide resolved
@oxade oxade merged commit dae1ad2 into main Jan 19, 2022
@oxade oxade deleted the feature/move-object-basics-transfer-throughput-benchmark branch January 22, 2022 23:07
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.

None yet

4 participants