Add toggle for LRU
This commit is contained in:
parent
b695ca5a2a
commit
b5bec371ae
8 changed files with 61 additions and 11 deletions
|
@ -36,7 +36,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||
SHOW_APP_RAM_USAGE("show_app_ram_usage"),
|
||||
SHOW_SYSTEM_RAM_USAGE("show_system_ram_usage"),
|
||||
SHOW_BAT_TEMPERATURE("show_bat_temperature"),
|
||||
OVERLAY_BACKGROUND("overlay_background"),;
|
||||
OVERLAY_BACKGROUND("overlay_background"),
|
||||
USE_LRU_CACHE("use_lru_cache"),;
|
||||
external fun isFrameSkippingEnabled(): Boolean
|
||||
external fun isFrameInterpolationEnabled(): Boolean
|
||||
|
||||
|
|
|
@ -119,6 +119,13 @@ abstract class SettingsItem(
|
|||
// List of all general
|
||||
val settingsItems = HashMap<String, SettingsItem>().apply {
|
||||
put(StringInputSetting(StringSetting.DEVICE_NAME, titleId = R.string.device_name))
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.USE_LRU_CACHE,
|
||||
titleId = R.string.use_lru_cache,
|
||||
descriptionId = R.string.use_lru_cache_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.RENDERER_USE_SPEED_LIMIT,
|
||||
|
|
|
@ -251,6 +251,7 @@ class SettingsFragmentPresenter(
|
|||
add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key)
|
||||
add(IntSetting.RENDERER_ASTC_RECOMPRESSION.key)
|
||||
add(IntSetting.RENDERER_VRAM_USAGE_MODE.key)
|
||||
add(BooleanSetting.USE_LRU_CACHE.key)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -471,6 +472,13 @@ class SettingsFragmentPresenter(
|
|||
descriptionId = R.string.frame_skipping_description
|
||||
)
|
||||
)
|
||||
add(
|
||||
SwitchSetting(
|
||||
BooleanSetting.USE_LRU_CACHE,
|
||||
titleId = R.string.use_lru_cache,
|
||||
descriptionId = R.string.use_lru_cache_description
|
||||
)
|
||||
)
|
||||
add(ByteSetting.RENDERER_DYNA_STATE.key)
|
||||
add(
|
||||
SwitchSetting(
|
||||
|
|
|
@ -49,6 +49,10 @@ struct Values {
|
|||
Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path",
|
||||
Settings::Category::GpuDriver};
|
||||
|
||||
// LRU Cache
|
||||
Settings::SwitchableSetting<bool> use_lru_cache{linkage, true, "use_lru_cache",
|
||||
Settings::Category::System};
|
||||
|
||||
Settings::Setting<s32> theme{linkage, 0, "theme", Settings::Category::Android};
|
||||
Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android};
|
||||
Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds",
|
||||
|
|
|
@ -655,6 +655,10 @@
|
|||
<string name="resolution_three">3X (2160p/3240p) (Slow)</string>
|
||||
<string name="resolution_four">4X (2880p/4320p) (Slow)</string>
|
||||
|
||||
<!-- LRU Cache -->
|
||||
<string name="use_lru_cache">Enable LRU Cache</string>
|
||||
<string name="use_lru_cache_description">Enable or disable the Least Recently Used (LRU) cache for improved performance</string>
|
||||
|
||||
<!-- Renderer VSync -->
|
||||
<string name="renderer_vsync_immediate">Immediate (Off)</string>
|
||||
<string name="renderer_vsync_mailbox">Mailbox</string>
|
||||
|
|
|
@ -218,6 +218,7 @@ struct Values {
|
|||
// Memory
|
||||
SwitchableSetting<bool> use_gpu_memory_manager{linkage, false, "Use GPU Memory Manager", Category::Core};
|
||||
SwitchableSetting<bool> enable_memory_snapshots{linkage, false, "Enable Memory Snapshots", Category::Core};
|
||||
SwitchableSetting<bool> lru_cache_enabled{linkage, true, "use_lru_cache", Category::System};
|
||||
|
||||
// Cpu
|
||||
SwitchableSetting<CpuBackend, true> cpu_backend{linkage,
|
||||
|
|
|
@ -6,13 +6,21 @@
|
|||
|
||||
template<typename KeyType, typename ValueType>
|
||||
class LRUCache {
|
||||
private:
|
||||
bool enabled = true;
|
||||
size_t capacity;
|
||||
std::list<KeyType> cache_list;
|
||||
std::unordered_map<KeyType, std::pair<typename std::list<KeyType>::iterator, ValueType>> cache_map;
|
||||
|
||||
public:
|
||||
explicit LRUCache(size_t capacity) : capacity(capacity) {
|
||||
explicit LRUCache(size_t capacity, bool enabled = true) : enabled(enabled), capacity(capacity) {
|
||||
cache_map.reserve(capacity);
|
||||
}
|
||||
|
||||
// Returns pointer to value if found, nullptr otherwise
|
||||
ValueType* get(const KeyType& key) {
|
||||
if (!enabled) return nullptr;
|
||||
|
||||
auto it = cache_map.find(key);
|
||||
if (it == cache_map.end()) {
|
||||
return nullptr;
|
||||
|
@ -25,12 +33,16 @@ public:
|
|||
|
||||
// Returns pointer to value if found (without promoting it), nullptr otherwise
|
||||
ValueType* peek(const KeyType& key) const {
|
||||
if (!enabled) return nullptr;
|
||||
|
||||
auto it = cache_map.find(key);
|
||||
return it != cache_map.end() ? &(it->second.second) : nullptr;
|
||||
}
|
||||
|
||||
// Inserts or updates a key-value pair
|
||||
void put(const KeyType& key, const ValueType& value) {
|
||||
if (!enabled) return;
|
||||
|
||||
auto it = cache_map.find(key);
|
||||
|
||||
if (it != cache_map.end()) {
|
||||
|
@ -52,6 +64,19 @@ public:
|
|||
cache_map[key] = {cache_list.begin(), value};
|
||||
}
|
||||
|
||||
// Enable or disable the LRU cache
|
||||
void setEnabled(bool state) {
|
||||
enabled = state;
|
||||
if (!enabled) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the cache is enabled
|
||||
bool isEnabled() const {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
// Attempts to get value, returns std::nullopt if not found
|
||||
std::optional<ValueType> try_get(const KeyType& key) {
|
||||
auto* val = get(key);
|
||||
|
@ -60,16 +85,18 @@ public:
|
|||
|
||||
// Checks if key exists in cache
|
||||
bool contains(const KeyType& key) const {
|
||||
if (!enabled) return false;
|
||||
return cache_map.find(key) != cache_map.end();
|
||||
}
|
||||
|
||||
// Removes a key from the cache if it exists
|
||||
bool erase(const KeyType& key) {
|
||||
if (!enabled) return false;
|
||||
|
||||
auto it = cache_map.find(key);
|
||||
if (it == cache_map.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cache_list.erase(it->second.first);
|
||||
cache_map.erase(it);
|
||||
return true;
|
||||
|
@ -83,7 +110,7 @@ public:
|
|||
|
||||
// Returns current number of elements in cache
|
||||
size_t size() const {
|
||||
return cache_map.size();
|
||||
return enabled ? cache_map.size() : 0;
|
||||
}
|
||||
|
||||
// Returns maximum capacity of cache
|
||||
|
@ -93,6 +120,8 @@ public:
|
|||
|
||||
// Resizes the cache, evicting LRU items if new capacity is smaller
|
||||
void resize(size_t new_capacity) {
|
||||
if (!enabled) return;
|
||||
|
||||
capacity = new_capacity;
|
||||
while (cache_map.size() > capacity) {
|
||||
auto last = cache_list.back();
|
||||
|
@ -101,9 +130,4 @@ public:
|
|||
}
|
||||
cache_map.reserve(capacity);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t capacity;
|
||||
std::list<KeyType> cache_list;
|
||||
std::unordered_map<KeyType, std::pair<typename std::list<KeyType>::iterator, ValueType>> cache_map;
|
||||
};
|
|
@ -10,6 +10,7 @@
|
|||
#include <oaknut/oaknut.hpp>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/hle/kernel/code_set.h"
|
||||
#include "core/hle/kernel/k_typed_address.h"
|
||||
#include "core/hle/kernel/physical_memory.h"
|
||||
|
@ -61,8 +62,8 @@ private:
|
|||
void WriteCntpctHandler(ModuleDestLabel module_dest, oaknut::XReg dest_reg);
|
||||
|
||||
private:
|
||||
static constexpr size_t CACHE_SIZE = 1024; // Cache size for patch entries
|
||||
LRUCache<uintptr_t, PatchTextAddress> patch_cache{CACHE_SIZE};
|
||||
static constexpr size_t CACHE_SIZE = 4096; // Cache size for patch entries
|
||||
LRUCache<uintptr_t, PatchTextAddress> patch_cache{CACHE_SIZE, Settings::values.lru_cache_enabled.GetValue()};
|
||||
|
||||
void BranchToPatch(uintptr_t module_dest) {
|
||||
// Try to get existing patch entry from cache
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue