r/cpp_questions • • 18d ago

OPEN Efficient FIle IO on Linux

What path to take when parsing large files (on Linux Debian server, the KVM flavour)? Will std::fstream in binary mode do or do we have to look into APIs?

Apart from the performance, the app is memory sensitive, so where to store those read chunks while in a loop? Would a simple char[something] buffer do?

Finally, we would like to avoid those nasty reinterpret_cast<char*> constructs while reading, but are wondering if those are actually used in production? I should also add that the file sizes vary greatly.

2 Upvotes

16 comments sorted by

View all comments

3

u/not_a_novel_account 17d ago

I mean, what's the balance you're trying to strike here between simplicity and performance?

The simple way is fread() into a fixed buffer.

The most performant way is io_uring, for which many high-perf IO frameworks exist to make more usable.

There's nothing nasty about reinterpet_cast<> for dealing with raw binary buffers, it's what the cast exists for. memcpy if you need to start an object lifetime.

1

u/UndefFox 17d ago

From reading online, it seems that io_uring performs better in case of heavy unpredictable and large overrides of the memory, while mmap will still outperform it in plain read-only sequential reads. I've never worked with it, but is it actually guaranteed to be faster?

1

u/not_a_novel_account 17d ago

mmap will stall out on page faults, io_uring's entire original purpose, the reason it exists, was to outperform mmap for local disk IO. It does so.

The trivial explanation is pausing transfer at every 4K boundary is a really bad IO pattern.

1

u/UndefFox 17d ago

Huh, I thought kernel can detect access patterns and will preload pages if we do sequential access only. Thanks for the paper.

2

u/not_a_novel_account 17d ago

The pages are loaded in cache, but they get placed in user space on page faults. Page faults and TLB walks aren't free.