From b45b91bf07289caa31f0fe1e68b5235c0f063ee6 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Sun, 20 Dec 2009 01:28:23 +0000 Subject: [PATCH] More minor improvements to cpuSpeed calculations, since my experimental fix apparently works. :) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2364 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/src/x86emitter/WinCpuDetect.cpp | 9 ++++++++- common/src/x86emitter/cpudetect.cpp | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/common/src/x86emitter/WinCpuDetect.cpp b/common/src/x86emitter/WinCpuDetect.cpp index af87a20a69..06888dd982 100644 --- a/common/src/x86emitter/WinCpuDetect.cpp +++ b/common/src/x86emitter/WinCpuDetect.cpp @@ -88,8 +88,15 @@ SingleCoreAffinity::SingleCoreAffinity() ); } - // Force Windows to timeslice (hoping this fixes some affinity issues) Sleep( 2 ); + + // Sleep Explained: I arbitrarily pick Core 0 to lock to for running the CPU test. This + // means that the current thread will need to be switched to Core 0 if it's currently + // scheduled on a difference cpu/core. However, Windows does not necessarily perform + // that scheduling immediately upon the call to SetThreadAffinityMask (seems dependent + // on version: XP does, Win7 does not). So by issuing a Sleep here we give Win7 time + // to issue a timeslice and move our thread to Core 0. Without this, it tends to move + // the thread during the cpuSpeed test instead, causing totally wacky results. }; SingleCoreAffinity::~SingleCoreAffinity() throw() diff --git a/common/src/x86emitter/cpudetect.cpp b/common/src/x86emitter/cpudetect.cpp index 3eb850297c..efbf17f424 100644 --- a/common/src/x86emitter/cpudetect.cpp +++ b/common/src/x86emitter/cpudetect.cpp @@ -34,7 +34,7 @@ static const char* bool_to_char( bool testcond ) static s64 CPUSpeedHz( u64 time ) { u64 timeStart, timeStop; - s64 startTick, endTick; + s64 startCycle, endCycle; if( ! x86caps.hasTimeStampCounter ) return 0; @@ -49,18 +49,28 @@ static s64 CPUSpeedHz( u64 time ) do { timeStop = GetCPUTicks(); - startTick = __rdtsc(); + startCycle = __rdtsc(); } while( ( timeStop - timeStart ) == 0 ); timeStart = timeStop; do { timeStop = GetCPUTicks(); - endTick = __rdtsc(); + endCycle = __rdtsc(); } while( ( timeStop - timeStart ) < time ); - return (s64)( endTick - startTick ); + s64 cycleCount = endCycle - startCycle; + s64 timeCount = timeStop - timeStart; + s64 overrun = timeCount - time; + if( !overrun ) return cycleCount; + + // interference could cause us to overshoot the target time, compensate: + + double cyclesPerTick = (double)cycleCount / (double)timeCount; + double newCycleCount = (double)cycleCount - (cyclesPerTick * overrun); + + return (s64)newCycleCount; } // Recompiled code buffer for SSE and MXCSR feature testing.