From d540d284b5711f044678191bbab858de626103a9 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 15 Aug 2021 15:35:53 +0200 Subject: VideoCore: Rework Garbage Collection. --- src/common/lru_cache.h | 141 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 src/common/lru_cache.h (limited to 'src/common') diff --git a/src/common/lru_cache.h b/src/common/lru_cache.h new file mode 100644 index 000000000..048e9c3da --- /dev/null +++ b/src/common/lru_cache.h @@ -0,0 +1,141 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2+ or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include + +#include "common/common_types.h" + +namespace Common { + +template +class LeastRecentlyUsedCache { + using ObjectType = typename Traits::ObjectType; + using TickType = typename Traits::TickType; + + struct Item { + ObjectType obj; + TickType tick; + Item* next{}; + Item* prev{}; + }; + +public: + LeastRecentlyUsedCache() : first_item{}, last_item{} {} + ~LeastRecentlyUsedCache() = default; + + size_t Insert(ObjectType obj, TickType tick) { + const auto new_id = build(); + auto& item = item_pool[new_id]; + item.obj = obj; + item.tick = tick; + attach(item); + return new_id; + } + + void Touch(size_t id, TickType tick) { + auto& item = item_pool[id]; + if (item.tick >= tick) { + return; + } + item.tick = tick; + if (&item == last_item) { + return; + } + detach(item); + attach(item); + } + + void Free(size_t id) { + auto& item = item_pool[id]; + detach(item); + item.prev = nullptr; + item.next = nullptr; + free_items.push_back(id); + } + + template + void ForEachItemBelow(TickType tick, Func&& func) { + static constexpr bool RETURNS_BOOL = + std::is_same_v, bool>; + Item* iterator = first_item; + while (iterator) { + if (static_cast(tick) - static_cast(iterator->tick) < 0) { + return; + } + Item* next = iterator->next; + if constexpr (RETURNS_BOOL) { + if (func(iterator->obj)) { + return; + } + } else { + func(iterator->obj); + } + iterator = next; + } + } + +private: + size_t build() { + if (free_items.empty()) { + const size_t item_id = item_pool.size(); + item_pool.emplace_back(); + auto& item = item_pool[item_id]; + item.next = nullptr; + item.prev = nullptr; + return item_id; + } + const size_t item_id = free_items.front(); + free_items.pop_front(); + auto& item = item_pool[item_id]; + item.next = nullptr; + item.prev = nullptr; + return item_id; + } + + void attach(Item& item) { + if (!first_item) { + first_item = &item; + } + if (!last_item) { + last_item = &item; + } else { + item.prev = last_item; + last_item->next = &item; + item.next = nullptr; + last_item = &item; + } + } + + void detach(Item& item) { + if (item.prev) { + item.prev->next = item.next; + } + if (item.next) { + item.next->prev = item.prev; + } + if (&item == first_item) { + first_item = item.next; + if (first_item) { + first_item->prev = nullptr; + } + } + if (&item == last_item) { + last_item = item.prev; + if (last_item) { + last_item->next = nullptr; + } + } + } + + std::deque item_pool; + std::deque free_items; + Item* first_item; + Item* last_item; +}; + +} // namespace Common -- cgit v1.2.3 From ba82bb359bac918bf0d048fcd21d13c426bcd336 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 8 Aug 2021 12:32:09 +0200 Subject: Garbage Collection: enable as default, eliminate option. --- src/common/settings.cpp | 2 -- src/common/settings.h | 1 - 2 files changed, 3 deletions(-) (limited to 'src/common') diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 996315999..fd3b639cd 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -59,7 +59,6 @@ void LogSettings() { log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); - log_setting("Renderer_UseGarbageCollection", values.use_caches_gc.GetValue()); log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); log_setting("Audio_OutputEngine", values.sink_id.GetValue()); log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); @@ -143,7 +142,6 @@ void RestoreGlobalState(bool is_powered_on) { values.shader_backend.SetGlobal(true); values.use_asynchronous_shaders.SetGlobal(true); values.use_fast_gpu_time.SetGlobal(true); - values.use_caches_gc.SetGlobal(true); values.bg_red.SetGlobal(true); values.bg_green.SetGlobal(true); values.bg_blue.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 20769d310..ec4d381e8 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -475,7 +475,6 @@ struct Values { ShaderBackend::SPIRV, "shader_backend"}; Setting use_asynchronous_shaders{false, "use_asynchronous_shaders"}; Setting use_fast_gpu_time{true, "use_fast_gpu_time"}; - Setting use_caches_gc{false, "use_caches_gc"}; Setting bg_red{0, "bg_red"}; Setting bg_green{0, "bg_green"}; -- cgit v1.2.3 From ff48f06fb92e5fe2105fd6b4c5d4f57bbb2714c7 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 29 Aug 2021 18:19:53 +0200 Subject: Garbage Collection: Adress Feedback. --- src/common/lru_cache.h | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/common') diff --git a/src/common/lru_cache.h b/src/common/lru_cache.h index 048e9c3da..365488ba5 100644 --- a/src/common/lru_cache.h +++ b/src/common/lru_cache.h @@ -29,11 +29,11 @@ public: ~LeastRecentlyUsedCache() = default; size_t Insert(ObjectType obj, TickType tick) { - const auto new_id = build(); + const auto new_id = Build(); auto& item = item_pool[new_id]; item.obj = obj; item.tick = tick; - attach(item); + Attach(item); return new_id; } @@ -46,13 +46,13 @@ public: if (&item == last_item) { return; } - detach(item); - attach(item); + Detach(item); + Attach(item); } void Free(size_t id) { auto& item = item_pool[id]; - detach(item); + Detach(item); item.prev = nullptr; item.next = nullptr; free_items.push_back(id); @@ -80,11 +80,10 @@ public: } private: - size_t build() { + size_t Build() { if (free_items.empty()) { const size_t item_id = item_pool.size(); - item_pool.emplace_back(); - auto& item = item_pool[item_id]; + auto& item = item_pool.emplace_back(); item.next = nullptr; item.prev = nullptr; return item_id; @@ -97,7 +96,7 @@ private: return item_id; } - void attach(Item& item) { + void Attach(Item& item) { if (!first_item) { first_item = &item; } @@ -111,7 +110,7 @@ private: } } - void detach(Item& item) { + void Detach(Item& item) { if (item.prev) { item.prev->next = item.next; } @@ -134,8 +133,8 @@ private: std::deque item_pool; std::deque free_items; - Item* first_item; - Item* last_item; + Item* first_item{}; + Item* last_item{}; }; } // namespace Common -- cgit v1.2.3