mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-13 19:00:43 +02:00
L1 cache residency can get quite large. Solution, start out small and scale quickly on L1 cache misses but L2/L3 cache hits. Some stats on L1 cache residency change: - Teardown: 40MB -> 16MB (40%) - Ender Lilies: 79MB -> 32MB (40.5%) - Death Stranding: 186MB -> 93MB (50%) - Steam: 75MB -> 7MB (9.3%) The cost of this option is effectively free in our JIT. It changes a single LDR to be a single LDP, which on Cortex CPUs cost the same. We do this by moving the L1 pointer mask in to the CPUState object, making it dynamic so it lives next to the L1 pointer. We then use that directly rather than having the hardcoded value. The lookup cache does a little bit of additional tracking and heuristics to determine when the current L1 cache should increase or decrease in size. From 128KB to 16MB per thread, allocating the full VA range as previously. Once the heuristic determines that L1 should be increased, it simply changes the max and the L1 pointer size to compensate, the kernel will fault in whichever pages are necessary. Decreasing the size is a little bit more complex, as we want to madvise the resulting L1 range to ensure we don't have that memory as resident anymore. Same heuristic but going in the opposite direction otherwise. Tends to be the case that L1 cache increases a bit on loading screens then backs down once in-game. These heuristic values are exposed for increasing and decreasing because while I think I've picked reasonable values, we will likely need some more fine tuning over time. Kind of expert user toggles at that point. Based on #4940 as a base which needs to be merged first. Full tracked stats from steam as an example of where we are: ``` Total (1000 millisecond sample period): JIT Time: 0.486630 ms/second (0.00 percent) Signal Time: 0.065880 ms/second (0.00 percent) SIGBUS Cnt: 38 (38.160780 per second) SMC Cnt: 0 Softfloat Cnt: 0 FEX JIT Load: 0.004585 (cycles: 552510) Total FEX Anon memory resident: 368 mB JIT resident: 95 mB OpDispatcher resident: 38 mB Frontend resident: 8 mB CPUBackend resident: 624 kB Lookup cache resident: 0 (null) Lookup L1 cache resident: 7 mB ThreadStates resident: 460 kB Unaccounted resident: 217 mB ```