-
Notifications
You must be signed in to change notification settings - Fork 632
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
Fee estimator using QEMU instrumentation: Read I/O bytes seem to be wrong #5678
Comments
Ok, after deeper analysis, I think the counters are fine. It was my understanding of what we measure that was wrong. TLDR: Having zero IO in
More detailed findingsBasically, my (wrong) assumption was that every byte of reading storage should correspond to some read-IO bytes. And that measurements of the two should increase hand-in-hand. But the relationship is much more delicate than that. It heavily depends on the storage internals, i.e. RocksDB. (A good resource I found on these internals is the high-level architecture overview in the RocksDB wiki.) On a high-level, I believe that in our setup, most requests to RocksDB are handled inside memtable, which is an in-memory write buffer. Only once the memtable flushes can we expect IO traffic. Interestingly, the flush will involve a series of complex things, such as data compression and creations/merges of so-called SST files. This will cause a bulk of read and write IO, as well as significant CPU load all at once. Now, I think it is reasonable to have zero IO bytes in many situations, due to this memtable not being flushed in short transactions. And that's probably okay for the estimator. The test for But this raises the question, why did I observe write IO even without flushes? This is because of the Write-Ahead-Log (WAL), which keeps a record of all non-flushed DB transactions. On top of executing the changes inside the memtable, a copy of each write-transaction is always written directly to this WAL, which is in persistent storage. This is to allow recovery after e.g. a power outage, where the content in the memtable would be lost. Ok, I explained the IO measurements in the base cases. ( In conclusion, if I had just thought a bit more about what we are measuring exactly, then the numbers would have made more sense. I guess, at least it was a good exercise for me to learn how our DB works and also how to debug the QEMU plugin. |
Excellent analysis! I think one thing I am not entirely 100% sure about is
It might be possible to read something that's not in memtable. Like, what if we spread-out writes in the benchmark some more? |
Indeed we can! Simply increasing the setup write loop counter from 1000 to 100_000, while keeping the reads the same, gives me this result:
The amount of read-IO just exploded! Somewhat expected, it also massively increases the time to compute the results. I also tried 10_000 iterations but it still had 0 reads. I guess I can do a binary-search to find the sweet-spot. :-) More importantly, the number of read IO seems way too high. I am not sure how to interpret this huge increase. I suspect it could be related to the observations investigated in #4771. But I will have to look at the details after the weekend. And then there is also a more general discussion to be had here. I am not sure if we want to force a read from disk for this specific parameter. On one hand, security-wise it sounds very reasonable that we want to estimate for the worst case, so no data in memory whatsoever. What I am thinking is that in a perfect world, we should only charge the user for loading a block when it actually happens. For example, it looks like we have 16kB blocks right now. So if a contract can keep it's data within 16kB, no matter how often it reads from that data, it should only pay the huge overhead of loading the block into memory once. But it's probably not that easy to do that. |
When running the fee estimator, I always get 0 IO read bytes. Even on
StorageReadBase
, which I would assume should have read IO.To Reproduce
Output then shows 0r, which is the counter for read IO bytes.
Expected behavior
There should be a positive number for the read IO bytes counter.
Version (please complete the following information):
After merge of #5677
Additional context
Additional note: I found that without warming up for at least 1 iteration (
--warmup-iters 1
) theStorageReadBase
crashes because in the first round, thenoop_function_call_cost
inruntime/runtime-params-estimator/src/lib.rs:506
returns 5 byte of Read IO. This causestotal_cost - base_cost
on line 510 to underflow.With the warm up, this is okay because later calls have no read cost.
The text was updated successfully, but these errors were encountered: