Skip to content

Follow-up: making the custom disk cache actually help (~840 MB/s on 10G/NVMe) #8419

Description

@tjjh89017

Quick follow-up to #7764, where adding a cache in front of our raw-disk storage made things slower (350-400 MB/s vs 450-600 without, network thoughtput).

(EZIO writes to a raw partition, not a filesystem. Torrent "files" are hex disk offsets, blocks in a piece are physically contiguous. Target is 10G+ LAN + NVMe.)

Why the first cache was slower: it was a shared map + mutex (plus a store_buffer for read-after-write ordering). With aio_threads disk threads all hitting one lock per block, it was a serialization point. The lock ate all of them.

The fix was partitioning instead of locking: Route every block of a piece to one worker thread: hash (storage, piece) (deliberately not the offset) to pick a partition, one thread owns one partition.

  • No mutex anywhere: a partition is only touched by its owner, so map/LRU/stats need no locking.
  • Read-after-write ordering without store_buffer: same piece always lands on the same thread, so async_read naturally queues behind async_write. Deleted the whole store_buffer.

The reason offset can't go into the hash: async_hash reads a piece's blocks straight from the cache, so scattering them across partitions reintroduces the race you just removed. Keeping a whole piece thread-local is what keeps it lock-free.

Result on 1-on-1 (--cache-size 4096 --aio-threads 16, 60 GiB, NVMe both ends): download rate sustains ~840 MB/s, peaks ~870, 98-100% hit rate. Flush-to-disk is slower (~540 MiB/s) and that's the point, the cache lets the network run ahead of the disk.

Code: https://github.com/tjjh89017/ezio (raw_disk_io.cpp + the lock-free cache).

Thanks @arvidn again always.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions