From 1af781c0a558b4448f04634d3679a67143145e21 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Tue, 26 Jul 2022 19:35:47 +0530 Subject: [PATCH] Add Perfetto Tracing to NCE Trapping API As a performance sensitive part of code, the NCE Trapping API benefits from having tracing and it helps us better determine where guest code is spending its time for more targeted optimizations. --- app/src/main/cpp/skyline/common/trace.h | 1 + app/src/main/cpp/skyline/gpu/buffer.cpp | 4 ++++ app/src/main/cpp/skyline/gpu/texture/texture.cpp | 4 ++++ app/src/main/cpp/skyline/nce.cpp | 9 +++++++++ 4 files changed, 18 insertions(+) diff --git a/app/src/main/cpp/skyline/common/trace.h b/app/src/main/cpp/skyline/common/trace.h index 11de4045..78823c44 100644 --- a/app/src/main/cpp/skyline/common/trace.h +++ b/app/src/main/cpp/skyline/common/trace.h @@ -12,6 +12,7 @@ PERFETTO_DEFINE_CATEGORIES( perfetto::Category("scheduler").SetDescription("Events from the HLE scheduler"), perfetto::Category("kernel").SetDescription("Events from parts of the HLE kernel"), perfetto::Category("guest").SetDescription("Events relating to guest code"), + perfetto::Category("host").SetDescription("Events relating to host code"), perfetto::Category("gpu").SetDescription("Events from the emulated GPU"), perfetto::Category("service").SetDescription("Events from the HLE sysmodule implementations"), perfetto::Category("containers").SetDescription("Events from custom container implementations") diff --git a/app/src/main/cpp/skyline/gpu/buffer.cpp b/app/src/main/cpp/skyline/gpu/buffer.cpp index b569d908..0c18185d 100644 --- a/app/src/main/cpp/skyline/gpu/buffer.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer.cpp @@ -23,6 +23,8 @@ namespace skyline::gpu { return; std::scoped_lock lock{*buffer}; }, [weakThis] { + TRACE_EVENT("gpu", "Buffer::ReadTrap"); + auto buffer{weakThis.lock()}; if (!buffer) return true; @@ -34,6 +36,8 @@ namespace skyline::gpu { return true; }, [weakThis] { + TRACE_EVENT("gpu", "Buffer::WriteTrap"); + auto buffer{weakThis.lock()}; if (!buffer) return true; diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index 0a6b99cd..4431c750 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -152,6 +152,8 @@ namespace skyline::gpu { std::scoped_lock lock{*texture}; }, [weakThis] { + TRACE_EVENT("gpu", "Texture::ReadTrap"); + auto texture{weakThis.lock()}; if (!texture) return true; @@ -164,6 +166,8 @@ namespace skyline::gpu { texture->WaitOnFence(); return true; }, [weakThis] { + TRACE_EVENT("gpu", "Texture::WriteTrap"); + auto texture{weakThis.lock()}; if (!texture) return true; diff --git a/app/src/main/cpp/skyline/nce.cpp b/app/src/main/cpp/skyline/nce.cpp index 01c9630a..aa284715 100644 --- a/app/src/main/cpp/skyline/nce.cpp +++ b/app/src/main/cpp/skyline/nce.cpp @@ -409,6 +409,8 @@ namespace skyline::nce { NCE::CallbackEntry::CallbackEntry(TrapProtection protection, LockCallback lockCallback, TrapCallback readCallback, TrapCallback writeCallback) : protection{protection}, lockCallback{std::move(lockCallback)}, readCallback{std::move(readCallback)}, writeCallback{std::move(writeCallback)} {} void NCE::ReprotectIntervals(const std::vector &intervals, TrapProtection protection) { + TRACE_EVENT("host", "NCE::ReprotectIntervals"); + auto reprotectIntervalsWithFunction = [&intervals](auto getProtection) { for (auto region : intervals) { region = region.Align(PAGE_SIZE); @@ -455,6 +457,7 @@ namespace skyline::nce { }); // Page out regions that are no longer accessible, these should be paged back in by a callback + TRACE_EVENT("host", "NCE::ReprotectIntervals::PageOut"); for (auto region : intervals) { auto freeStart{util::AlignUp(region.start, PAGE_SIZE)}, freeEnd{util::AlignDown(region.end, PAGE_SIZE)}; // We want to avoid the first and last page as they may contain data that won't be paged back in by the callback ssize_t freeSize{freeEnd - freeStart}; @@ -467,6 +470,8 @@ namespace skyline::nce { } bool NCE::TrapHandler(u8 *address, bool write) { + TRACE_EVENT("host", "NCE::TrapHandler"); + LockCallback lockCallback{}; while (true) { if (lockCallback) { @@ -531,6 +536,7 @@ namespace skyline::nce { constexpr NCE::TrapHandle::TrapHandle(const TrapMap::GroupHandle &handle) : TrapMap::GroupHandle(handle) {} NCE::TrapHandle NCE::TrapRegions(span> regions, bool writeOnly, const LockCallback &lockCallback, const TrapCallback &readCallback, const TrapCallback &writeCallback) { + TRACE_EVENT("host", "NCE::TrapRegions"); std::scoped_lock lock(trapMutex); auto protection{writeOnly ? TrapProtection::WriteOnly : TrapProtection::ReadWrite}; TrapHandle handle{trapMap.Insert(regions, CallbackEntry{protection, lockCallback, readCallback, writeCallback})}; @@ -539,6 +545,7 @@ namespace skyline::nce { } void NCE::RetrapRegions(TrapHandle handle, bool writeOnly) { + TRACE_EVENT("host", "NCE::RetrapRegions"); std::scoped_lock lock(trapMutex); auto protection{writeOnly ? TrapProtection::WriteOnly : TrapProtection::ReadWrite}; handle->value.protection = protection; @@ -546,12 +553,14 @@ namespace skyline::nce { } void NCE::RemoveTrap(TrapHandle handle) { + TRACE_EVENT("host", "NCE::RemoveTrap"); std::scoped_lock lock(trapMutex); handle->value.protection = TrapProtection::None; ReprotectIntervals(handle->intervals, TrapProtection::None); } void NCE::DeleteTrap(TrapHandle handle) { + TRACE_EVENT("host", "NCE::DeleteTrap"); std::scoped_lock lock(trapMutex); handle->value.protection = TrapProtection::None; ReprotectIntervals(handle->intervals, TrapProtection::None);