From 846178a588cf9aca06b0f67fafcc5ad11d1f5bc8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 15 Aug 2013 01:26:16 -0700 Subject: [PATCH] Optimize thread switching a bit. ~2.5% improvement in Zettai Hero Project (while multithreading.) --- Core/HLE/sceKernelThread.cpp | 22 ++++++---------------- Core/HLE/sceKernelThread.h | 20 ++++++++++++++------ Core/MIPS/MIPS.h | 24 +++++++++++++++--------- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 230191cae7..04d59d1488 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1412,8 +1412,8 @@ u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 i // Saves the current CPU context void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled) { - memcpy(ctx->r, currentMIPS->r, sizeof(ctx->r)); - memcpy(ctx->f, currentMIPS->f, sizeof(ctx->f)); + // r and f are immediately next to each other and must be. + memcpy(ctx->r, currentMIPS->r, sizeof(ctx->r) + sizeof(ctx->f)); if (vfpuEnabled) { @@ -1421,19 +1421,14 @@ void __KernelSaveContext(ThreadContext *ctx, bool vfpuEnabled) memcpy(ctx->vfpuCtrl, currentMIPS->vfpuCtrl, sizeof(ctx->vfpuCtrl)); } - ctx->pc = currentMIPS->pc; - ctx->hi = currentMIPS->hi; - ctx->lo = currentMIPS->lo; - ctx->fcr0 = currentMIPS->fcr0; - ctx->fcr31 = currentMIPS->fcr31; - ctx->fpcond = currentMIPS->fpcond; + memcpy(ctx->other, currentMIPS->other, sizeof(ctx->other)); } // Loads a CPU context void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled) { - memcpy(currentMIPS->r, ctx->r, sizeof(ctx->r)); - memcpy(currentMIPS->f, ctx->f, sizeof(ctx->f)); + // r and f are immediately next to each other and must be. + memcpy(currentMIPS->r, ctx->r, sizeof(ctx->r) + sizeof(ctx->f)); if (vfpuEnabled) { @@ -1441,12 +1436,7 @@ void __KernelLoadContext(ThreadContext *ctx, bool vfpuEnabled) memcpy(currentMIPS->vfpuCtrl, ctx->vfpuCtrl, sizeof(ctx->vfpuCtrl)); } - currentMIPS->pc = ctx->pc; - currentMIPS->hi = ctx->hi; - currentMIPS->lo = ctx->lo; - currentMIPS->fcr0 = ctx->fcr0; - currentMIPS->fcr31 = ctx->fcr31; - currentMIPS->fpcond = ctx->fpcond; + memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other)); // Reset the llBit, the other thread may have touched memory. currentMIPS->llBit = 0; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index e931f959f4..147677ce1e 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -109,19 +109,27 @@ void __KernelRegisterWaitTypeFuncs(WaitType type, WaitBeginCallbackFunc beginFun struct ThreadContext { void reset(); + + // r must be followed by f. u32 r[32]; float f[32]; + float v[128]; u32 vfpuCtrl[16]; - u32 pc; + union { + struct { + u32 pc; - u32 hi; - u32 lo; + u32 hi; + u32 lo; - u32 fcr0; - u32 fcr31; - u32 fpcond; + u32 fcr0; + u32 fcr31; + u32 fpcond; + }; + u32 other[6]; + }; }; // Internal API, used by implementations of kernel functions diff --git a/Core/MIPS/MIPS.h b/Core/MIPS/MIPS.h index 3503c7c73a..5ac5a7c99f 100644 --- a/Core/MIPS/MIPS.h +++ b/Core/MIPS/MIPS.h @@ -107,7 +107,7 @@ public: void Reset(); void DoState(PointerWrap &p); - // MUST start with r! + // MUST start with r and be followed by f! u32 r[32]; union { float f[32]; @@ -122,17 +122,23 @@ public: // If vfpuCtrl (prefixes) get mysterious values, check the VFPU regcache code. u32 vfpuCtrl[16]; - u32 pc; + union { + struct { + u32 pc; + + u32 hi; + u32 lo; + + u32 fcr0; + u32 fcr31; //fpu control register + u32 fpcond; // cache the cond flag of fcr31 (& 1 << 23) + }; + u32 other[6]; + }; + u32 nextPC; int downcount; // This really doesn't belong here, it belongs in CoreTiming. But you gotta do what you gotta do, this needs to be reachable in the ARM JIT. - u32 hi; - u32 lo; - - u32 fcr0; - u32 fcr31; //fpu control register - u32 fpcond; // cache the cond flag of fcr31 (& 1 << 23) - bool inDelaySlot; int llBit; // ll/sc