IntersectMBO / IntersectMBO/ouroboros-consensus
Investigate and optimise disk write performance
- Dominant language
- Haskell
- Stars
- 67
- Forks
- 43
- Avg merge
- 5d 13h
- Merged PRs (30d)
- 43
Description
When chain syncing, the synchronous write of the block to the VolatileDB is in the critical path. The write is done [here](https://github.com/input-output-hk/ouroboros-network/blob/a43961c1133b9e1b0826f3d4d1bc5b93819037d6/ouroboros-consensus/src/Ouroboros/Storage/VolatileDB/Impl.hs#L346) using [`hPut`](https://github.com/input-output-hk/ouroboros-network/blob/a43961c1133b9e1b0826f3d4d1bc5b93819037d6/ouroboros-consensus/src/Ouroboros/Storage/FS/API.hs#L275), which performs two loops: one in [`hPutAll`](https://github.com/input-output-hk/ouroboros-network/blob/a43961c1133b9e1b0826f3d4d1bc5b93819037d6/ouroboros-consensus/src/Ouroboros/Storage/FS/API.hs#L258) to write all chunks of the lazy bytestring using `hPutAllStrict` and one in [`hPutAllStrict`](https://github.com/input-output-hk/ouroboros-network/blob/a43961c1133b9e1b0826f3d4d1bc5b93819037d6/ouroboros-consensus/src/Ouroboros/Storage/FS/API.hs#L243) to handle partial writes.
I have run the following simple microbenchmark: let a client node sync from scratch with another fully synced server node running on the same machine and see how many blocks the client node manages to download in 1 minute. I ran each test twice. First using `hPutAll`, i.e., what we currently use, and once using `hPutSome`, since I haven't encountered a partial write on my machine anyway.
| Implementation | First run | Second run |
|----------------|-----------|------------|
| `hPutAll` | 57544 | 57296 |
| `hPutSome` | 63207 | 64962 |
On average that's a difference of **11%**.
I suspect the way `hPutAll` is written prevents some inlining or optimisations from kicking in.
To properly investigate this, we'll need a more isolated benchmark, as chain syncing involves a lot more than writing to disk.
Contributor guide
Assessment
This issue has not been assessed yet.