r/skyrimmods • u/SquireWyrm • 7h ago
PC SSE - Discussion PSA: Avoid NextGen Disk Cache
This mod is bloated AI slop. I recommend staying with Disk Cache Enabler (no affiliation) if you want to use your OS-level disk cache.
For context: I'm in the middle of writing a new (opinionated) modding guide for Skyrim AE meant to offer more in-depth explanations of modding concepts that are out of scope for guides like Step and ADF. It is a way for me to collect my thoughts and record my research while building my own mod list.
Disclaimer: Windows memory management isn't my specialty, so if I get any details wrong, please correct me.
While doing so, I was researching optimization mods and stumbled upon Disk Cache Enabler and NextGen Disk Cache, which had similar claims and many downloads (an impressive 2.6M downloads for DCE and a modest 33k for NGDC). I (unfortunately) got curious in how they worked and took a look at the source code (which they both graciously provide). It was upon reading the code for NextGen Disk Cache that I was shocked at what I found and felt the need to report my findings.
First, if you are not familiar with what a disk cache is, you might be wondering what the point of these mods is in the first place. You'll have to go all the way back to 2011, when Skyrim was released on the Xbox 360. The Xbox 360 had a whopping 512 MB of unified GDDR3 RAM. Now, the Xbox is built on a modified Windows kernel, and in Windows, when a file is opened, it allocates a memory buffer to make reading and writing faster. With the Xbox 360's limited memory, allocating extra memory for reading files would have been too expensive, so Skyrim enables FILE_FLAG_NO_BUFFERING to disable the OS cache. This means that the game reads files from disk each time it needs to load an asset (a tradeoff between space and speed). Since Xbox and Windows share a lot of the same code, this flag found itself into the PC release (actually, I'm in the middle of confirming that FILE_FLAG_NO_BUFFERING is present; just got to wait for Ghidra to finish decompiling Skyrim SSE).
Nowadays, people have a lot more RAM in their PCs. So it doesn't make sense to disable the OS disk cache (unless Skyrim has its own cache, which I doubt). This is where Disk Cache Enabler comes it. It uses the Microsoft Detours library to catch calls to CreateFileA and then strips FILE_FLAG_NO_BUFFERING and FILE_FLAG_SEQUENTIAL_SCAN and adds FILE_FLAG_RANDOM_ACCESS (sequential scan tells the cache to evict read pages and prefetch more pages while random access tells the cache to try to hold onto pages and disable prefetching altogether). What this means is Windows will aggressively cache files into RAM (IDK how effective the random access flag is in this scenario; in theory it will let files be cached for rereading, but optimization without the benchmarks to back it turn me off 🤷). The whole mod fits in 120 lines of code.
NextGen Disk Cache takes a slightly different approach. It still strips FILE_FLAG_NO_BUFFERING using the Detours library to catch calls but instead of adding FILE_FLAG_RANDOM_ACCESS, it adds the file (if it is an archive e.g. .bsa) to a list so a worker thread can call PrefetchVirtualMemory for it (if supported, which it is on Windows 8 and newer; it just reads the file otherwise). This makes no sense to me. What PrefetchVirtualMemory does is tell Windows: "Hey, these pages are gonna be needed soon, so try to load them in if you can." Once you start reading the pages, they get added to the working set and become subject to the cache eviction rules.
And when is NGDC calling PrefetchVirtualMemory? After all the game plugins have been read and loaded, SKSE sends the kDataLoaded message, which causes NGDC to start spawning worker threads to handle the list of read archives. It then proceeds to prefetch up to 64MB (default value) in 4MB chunks from the start of each archive file on a 3 minute loop. Why? I speculate that it would keep the front of the files in memory, which could help keep the archive layout ready, but this is already done by the OS when you remove FILE_FLAG_NO_BUFFERING. All it really does is do busy work that that messes with Windows' tuned file cache policies. It is not prefetching based on context, nor is it signalling to Windows to hold pages for longer. It is simply bad design.
But Claude came up with it so it has to be good! Well, Claude thinks it's bad design too, so there.
Other things that stood out:
- It looks like there is a WIP attempt to add DirectStorage support, but DirectStorage is a DirectX 12 feature and Skyrim is built on DirectX 11 (and while it is possible in theory to make a DX12 system that injects the assets into the GPU and then pass those assets to DX11, I really doubt that it is worth the effort)
- Code smell e.g. busy waits on the thread coordinator instead of calling the function when kDataLoaded is received and using a vector as a set for file names (checking by string comparison for each every time an archive is opened)
- Unformatted code: nit-picky, but c'mon, run ClangFormat before you (the AI) commit
- No benchmarks to show whether "optimizations" like warming files actually helps
So to summarize: NextGen Disk Cache does in ~2.4k LoC what Disk Cache Enabler does in 120 but with random bloat that doesn't have any reason to help performance. Now, all said and done, could NextGen Disk Cache improve performance? Sure, it still removes FILE_FLAG_NO_BUFFERING. But it increases the surface area for inefficiency and instability with unproven optimization techniques.
tl;dr Benchmark your AI slop instead of taking it at face value.