[Misc] Random optimizations.

- Seems like it improves performance in debug, not sure about release

- Stuff suggested by AI
This commit is contained in:
Gliniak
2026-08-13 22:46:34 +02:00
committed by Radosław Gliński
parent 4cc584f47d
commit a5a18f5c75
6 changed files with 36 additions and 17 deletions

View File

@@ -39,6 +39,14 @@ double guest_time_scalar_ = 1.0;
uint64_t guest_tick_frequency_ = Clock::host_tick_frequency_platform();
// Base FILETIME of the guest system from app start.
uint64_t guest_system_time_base_ = Clock::QueryHostSystemTime();
std::pair<uint64_t, uint64_t> guest_system_time_ratio_ =
[]() -> std::pair<uint64_t, uint64_t> {
std::pair<uint64_t, uint64_t> frac(uint64_t(10000000), guest_tick_frequency_);
reduce_fraction(frac);
return frac;
}();
// Combined time and frequency ratio between host and guest.
// Split in numerator (first) and denominator (second).
// Computed by RecomputeGuestTickScalar.
@@ -55,6 +63,13 @@ using tick_mutex_type = std::mutex;
// std::mutex tick_mutex_;
static tick_mutex_type tick_mutex_;
static void RecomputeGuestSystemTimeRatio() {
std::pair<uint64_t, uint64_t> frac(uint64_t(10000000), guest_tick_frequency_);
reduce_fraction(frac);
std::lock_guard<tick_mutex_type> lock(tick_mutex_);
guest_system_time_ratio_ = frac;
}
void RecomputeGuestTickScalar() {
// Create a rational number with numerator (first) and denominator (second)
auto frac =
@@ -111,11 +126,8 @@ inline uint64_t QueryGuestSystemTimeOffset() {
auto guest_tick_count = UpdateGuestClock();
uint64_t numerator = 10000000; // 100ns/10MHz resolution
uint64_t denominator = guest_tick_frequency_;
reduce_fraction(numerator, denominator);
return guest_tick_count * numerator / denominator;
return guest_tick_count * guest_system_time_ratio_.first /
guest_system_time_ratio_.second;
}
uint64_t Clock::QueryHostTickFrequency() {
#if XE_CLOCK_RAW_AVAILABLE
@@ -154,6 +166,7 @@ uint64_t Clock::guest_tick_frequency() { return guest_tick_frequency_; }
void Clock::set_guest_tick_frequency(uint64_t frequency) {
guest_tick_frequency_ = frequency;
RecomputeGuestSystemTimeRatio();
RecomputeGuestTickScalar();
}

View File

@@ -36,7 +36,7 @@ class StringBuffer {
template <typename... Args>
void AppendFormat(const char* format, const Args&... args) {
auto s = fmt::format(fmt::runtime(format), args...);
Append(s.c_str());
Append(std::string_view(s));
}
void AppendVarargs(const char* format, va_list args);

View File

@@ -3310,7 +3310,7 @@ bool SelectSequence(X64Emitter* e, const Instr* i, const Instr** new_tail) {
auto it = sequence_table.find(key);
if (it != sequence_table.end()) {
if (it->second(*e, i, InstrKey(i))) {
if (it->second(*e, i, key)) {
*new_tail = i->next;
return true;
}

View File

@@ -1624,7 +1624,7 @@ void RenderTargetCache::ChangeOwnership(
if (it_pre->second.end_tiles > extent_start &&
!it_pre->second.IsOwnedBy(dest, host_depth_encoding_different)) {
// Different render target overlapping the range - split the head.
ownership_ranges_.emplace(extent_start, it_pre->second);
ownership_ranges_.emplace_hint(it, extent_start, it_pre->second);
it_pre->second.end_tiles = extent_start;
// Let the next loop do the transfer and needed merging and splitting
// starting from the added tail.
@@ -1646,7 +1646,7 @@ void RenderTargetCache::ChangeOwnership(
// (split in this case) or within it.
if (it->second.end_tiles > extent_end) {
// Split the tail.
ownership_ranges_.emplace(extent_end, it->second);
ownership_ranges_.emplace_hint(std::next(it), extent_end, it->second);
it->second.end_tiles = extent_end;
}
if (transfers_append_out) {

View File

@@ -15,6 +15,7 @@
#include <cstdint>
#include <cstring>
#include <memory>
#include <type_traits>
#include <unordered_map>
#include "xenia/base/assert.h"
@@ -205,13 +206,8 @@ class TextureCache {
uint32_t is_valid : 1; // 98
TextureKey() { MakeInvalid(); }
TextureKey(const TextureKey& key) {
std::memcpy(this, &key, sizeof(*this));
}
TextureKey& operator=(const TextureKey& key) {
std::memcpy(this, &key, sizeof(*this));
return *this;
}
TextureKey(const TextureKey&) = default;
TextureKey& operator=(const TextureKey&) = default;
void MakeInvalid() {
// Zero everything, including the padding, for a stable hash.
std::memset(this, 0, sizeof(*this));
@@ -252,6 +248,10 @@ class TextureCache {
}
void LogAction(const char* action) const;
};
static_assert(
std::is_trivially_copyable_v<TextureKey>,
"TextureKey is compared and hashed by raw bytes; a trivial copy "
"is required so padding is carried and stays zero.");
class Texture {
public:

View File

@@ -556,7 +556,13 @@ struct ExportRegistrerHelper {
if (TAGS & xe::cpu::ExportTag::kLog &&
(!(TAGS & xe::cpu::ExportTag::kHighFrequency) ||
cvars::log_high_frequency_kernel_calls)) {
PrintKernelCall(export_entry, params);
const LogLevel needed_level =
(export_entry->tags & xe::cpu::ExportTag::kImportant)
? LogLevel::Info
: LogLevel::Debug;
if (logging::ShouldLog(needed_level, LogSrc::Kernel)) {
PrintKernelCall(export_entry, params);
}
}
if constexpr (std::is_void<R>::value) {
KernelTrampoline(fn, std::forward<std::tuple<Ps...>>(params),