From 0572073fced4eb6e6f684859beb438f7674db46d Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 6 Dec 2025 23:51:50 +0000 Subject: [PATCH] super align + nosync opts --- src/common/fs/file.cpp | 58 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/src/common/fs/file.cpp b/src/common/fs/file.cpp index 2c7efe6212..8ebf23ab70 100644 --- a/src/common/fs/file.cpp +++ b/src/common/fs/file.cpp @@ -13,6 +13,7 @@ #include "common/fs/fs_android.h" #endif #include "common/logging/log.h" +#include "common/literals.h" #ifdef _WIN32 #include @@ -273,18 +274,59 @@ void IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, File } else { file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); } -#elif defined(__unix__) && !defined(__HAIKU__) && !defined(__managarm__) +#elif defined(__HAIKU__) || defined(__managarm__) || defined(__OPENORBIS__) + file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); +#else if (type == FileType::BinaryFile && mode == FileAccessMode::Read) { struct stat st; mmap_fd = open(path.c_str(), O_RDONLY); fstat(mmap_fd, &st); mmap_size = st.st_size; - mmap_base = (u8*)mmap(nullptr, mmap_size, PROT_READ, MAP_PRIVATE, mmap_fd, 0); - } else { + + int map_flags = MAP_PRIVATE; +#ifdef MAP_PREFAULT_READ + // Prefaults reads so the final resulting pagetable from this big stupid mmap() + // isn't comically lazily loaded, we just coalesce everything in-place for our + // lovely mmap flags; if we didn't prefault the reads the page table will be + // constructed in-place (i.e on a read-by-read basis) causing lovely soft-faults + // which would nuke any performance gains. + // + // This of course incurs a cost in the initial mmap(2) call, but that is fine. + map_flags |= MAP_PREFAULT_READ; +#endif +#ifdef MAP_NOSYNC + // This causes physical media to not be synched to our file/memory + // This means that if the read-only file is written to, we won't see changes + // or we may see changes which are just funnily scattered, in any case + // this presumes the files won't be changed during execution + // + // Do not ever use this on write files (if we ever support that); this will create + // a fun amount of fragmentation on the disk. + map_flags |= MAP_NOSYNC; +#endif +#ifdef MAP_ALIGNED_SUPER + // File must be big enough that it's worth to super align. We can't just super-align every + // file otherwise we will run out of alignments for actually important files :) + // System doesn't guarantee a super alignment, but if it's available it will delete + // about 3 layers(?) of the TLB tree for each read/write. + // Again the cost of faults may make this negligible gains, but hey, we gotta work + // what we gotta work with. + using namespace Common::Literals; + u64 big_file_threshold = 512_MiB; + map_flags |= u64(st.st_size) >= big_file_threshold ? MAP_ALIGNED_SUPER : 0; +#endif + mmap_base = (u8*)mmap(nullptr, mmap_size, PROT_READ, map_flags, mmap_fd, 0); + if (mmap_base == MAP_FAILED) { + close(mmap_fd); + mmap_fd = -1; + } else { + posix_madvise(mmap_base, mmap_size, POSIX_MADV_WILLNEED); + } + } + // mmap(2) failed or simply we can't use it + if (mmap_fd == -1) { file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); } -#else - file = std::fopen(path.c_str(), AccessModeToStr(mode, type)); #endif if (!IsOpen()) { const auto ec = std::error_code{errno, std::generic_category()}; @@ -340,11 +382,7 @@ bool IOFile::Flush() const { #endif if (file) { errno = 0; -#ifdef _WIN32 - const auto flush_result = std::fflush(file) == 0; -#else - const auto flush_result = std::fflush(file) == 0; -#endif + auto const flush_result = std::fflush(file) == 0; if (!flush_result) { const auto ec = std::error_code{errno, std::generic_category()}; LOG_ERROR(Common_Filesystem, "Failed to flush the file at path={}, ec_message={}",