-
Notifications
You must be signed in to change notification settings - Fork 3.7k
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
Get and set account is kind of time consuming #2652
Comments
Thanks for pointing this out! We have plans for a cache mainly for generalized amino decodings. (i.e. an fully associative LRU "L2" cache ) I think it is very reasonable to make an "L1" cache just for account decoding though. I made such an example for a staking bottleneck awhile ago. I ran The good news is that I've already knocked off 3 percentage points of what was causing this amino delay, and we'll get that speed boost once we switch to the latest go-amino version in the sdk! But uhh, 3% is not that helpful. I'll briefly describe the amino bottlenecks in this particular situation (note: numbers are approximate).
So we should be able to drop the GetTime by a fifth just via fairly not hard amino upgrades, and then use an LRU cache to avoid duped decoding! /cc @liamsi |
Oh didn't notice this earlier. The implicit assumption of 4000 tps in the DApp is unrealistic in the current software, for a meaningfully long running chain. 4000 signature verifications will take much longer than a second. Even ignoring the signature verification time, KMS signing time, and the p2p network delay, the state tree will be balloon in size since we are in the account model with no pruning of old accounts. The state tree blow-up will then have I/O such that 4000 tps is no longer feasible. (Recall that at 4000 tps, each tx must take a quarter of a milisecond, its highly doubtful imo that sequential account reads will be on the similar enough iavl paths to facilitate this.) I am still all in favor of reducing this time, since I do agree that it seems too high for such a basic operation! |
Yeah, 4000 tps seems unreasonable now, just for an example. For now, amino takes too much time and signature verification as well. @ValarDragon I don't fully understand the L2 cache for amino, can you kindly give some more details? Actually, we kinda hope that we can also cache the IAVL tree in memory and do not clear the checkState and DeliverState at Commit stage. But IAVAL tree empties branches every time when committing, it is useless to remain DeliverState to next block. Is there any plan to not clearing IAVL tree when committing? |
So my point of view is that account state should be special cased for amino serialization and use a non-reflection based implemention either derived from a protobuf implementation or handrolled. I don't think we need to wait for some future amino compiler. I think the biggest thing is just figure out what the specialized serialization/deserialization interface should look like |
It seems the actionable item out of this for now is to create an "L1" LRU cache similar to what we do in staking. Amino improvements and modifications will come later. |
yeah, it is reasonable to add LRU cache to account, and replacement of amino can be done after that. but the use case of account is kind of different from validators. When getting an account from store, usually we want to change it. so we can not just simply cache the marshalled account. I did not dive into the use of the validator get from cache. but I have a concern that can we get a wrong state of validator if somewhere changes some properties of validator and not saves it to store for we do not deep copy the validator. @ValarDragon |
Agreed @zmanian! I think that would have a really large impact on over-all state machine performance. (Probably the most impact after we optimize IAVL performance and any asymptotic improvements) @yutianwu that'd be great! Here's an example you can model it off of: cosmos-sdk/x/stake/keeper/validator.go Line 12 in 60d188d
|
IMHO, the use case of account is different from validator. account is changed more frequently than validator. I think we should use the address of account as the key of the cache map and flush all changes to disk in Commit. What do you you think? @ValarDragon |
I have a rough idea:
But I have done a benchmark of deepcopy library, its performance is not that good for using reflect. PS: |
account structure has changed recently. The bank module is responsible for storing coin data about the account. Closing this issue, please reopen or carry the actionable into a new issue |
hi, recently, I have done some stress testing for our Dapp, I found that besides performance of secp256, encode and decode of account is also time consuming.
I have done a benchmark test in my laptop(MacBook Pro (15-inch, 2018), 2.2 GHz Intel Core i7).
GetAccount:
SetAccount
Assume that there is 4000tps in our dapp, set and get account will cost (16937 + 22989) * 4000 = 159.7 ms. The result is kind of unacceptable.
IMHO, I think we can cache the deserialized result so we may don't need to deserialize accounts again and again. It will save a half of the time.
The text was updated successfully, but these errors were encountered: