mirror of https://github.com/PCSX2/pcsx2.git
pcsx2:windows: Remove unused sampling profiler
Visual Studio has a much more powerful performance profiler which can do the same task and more.
This commit is contained in:
parent
ed47dca8a1
commit
38c802a4ef
|
@ -150,7 +150,6 @@ set(pcsx2Headers
|
|||
R5900Exceptions.h
|
||||
R5900.h
|
||||
R5900OpcodeTables.h
|
||||
SamplProf.h
|
||||
SaveState.h
|
||||
Sifcmd.h
|
||||
Sif.h
|
||||
|
@ -476,7 +475,6 @@ set(pcsx2WindowsSources
|
|||
windows/DwmSetup.cpp
|
||||
windows/ini.cpp
|
||||
windows/PatchBrowser.cpp
|
||||
windows/SamplProf.cpp
|
||||
windows/WinCompressNTFS.cpp
|
||||
windows/WinConsolePipe.cpp
|
||||
windows/WinSysExec.cpp)
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "Gif_Unit.h"
|
||||
#include "MTVU.h"
|
||||
#include "Elfheader.h"
|
||||
#include "SamplProf.h"
|
||||
|
||||
|
||||
// Uncomment this to enable profiling of the GS RingBufferCopy function.
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SAMPLPROF_H_
|
||||
#define _SAMPLPROF_H_
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
// The profiler does not have a Linux version yet.
|
||||
// So for now we turn it into duds for non-Win32 platforms.
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void ProfilerInit();
|
||||
void ProfilerTerm();
|
||||
void ProfilerSetEnabled(bool Enabled);
|
||||
void ProfilerRegisterSource(const char* Name, const void* buff, u32 sz);
|
||||
void ProfilerRegisterSource(const char* Name, const void* function);
|
||||
void ProfilerTerminateSource( const char* Name );
|
||||
|
||||
void ProfilerRegisterSource(const wxString& Name, const void* buff, u32 sz);
|
||||
void ProfilerRegisterSource(const wxString& Name, const void* function);
|
||||
void ProfilerTerminateSource( const wxString& Name );
|
||||
|
||||
#else
|
||||
|
||||
// Disables the profiler in Debug & Linux builds.
|
||||
// Profiling info in debug builds isn't much use anyway and the console
|
||||
// popups are annoying when you're trying to trace debug logs and stuff.
|
||||
|
||||
#define ProfilerInit() (void)0
|
||||
#define ProfilerTerm() (void)0
|
||||
#define ProfilerSetEnabled(...) (void)0
|
||||
#define ProfilerRegisterSource(...) (void)0
|
||||
#define ProfilerTerminateSource(...) (void)0
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -20,8 +20,6 @@
|
|||
#include "newVif.h"
|
||||
#include "MTVU.h"
|
||||
|
||||
#include "SamplProf.h"
|
||||
|
||||
#include "Elfheader.h"
|
||||
|
||||
#include "System/RecTypes.h"
|
||||
|
@ -43,8 +41,6 @@ RecompiledCodeReserve::RecompiledCodeReserve( const wxString& name, uint defComm
|
|||
m_blocksize = (1024 * 128) / __pagesize;
|
||||
m_prot_mode = PageAccess_Any();
|
||||
m_def_commit = defCommit / __pagesize;
|
||||
|
||||
m_profiler_registered = false;
|
||||
}
|
||||
|
||||
RecompiledCodeReserve::~RecompiledCodeReserve() throw()
|
||||
|
@ -55,17 +51,12 @@ RecompiledCodeReserve::~RecompiledCodeReserve() throw()
|
|||
void RecompiledCodeReserve::_registerProfiler()
|
||||
{
|
||||
if (m_profiler_name.IsEmpty() || !IsOk()) return;
|
||||
ProfilerRegisterSource( m_profiler_name, m_baseptr, GetReserveSizeInBytes() );
|
||||
m_profiler_registered = true;
|
||||
|
||||
// Could potentially be integrated into ProfilerRegisterSource
|
||||
Perf::any.map((uptr)m_baseptr, GetReserveSizeInBytes(), m_profiler_name.ToUTF8());
|
||||
}
|
||||
|
||||
void RecompiledCodeReserve::_termProfiler()
|
||||
{
|
||||
if (m_profiler_registered)
|
||||
ProfilerTerminateSource( m_profiler_name );
|
||||
}
|
||||
|
||||
uint RecompiledCodeReserve::_calcDefaultCommitInBlocks() const
|
||||
|
|
|
@ -34,7 +34,6 @@ protected:
|
|||
uint m_def_commit;
|
||||
|
||||
wxString m_profiler_name;
|
||||
bool m_profiler_registered;
|
||||
|
||||
public:
|
||||
RecompiledCodeReserve( const wxString& name=wxEmptyString, uint defCommit = 0 );
|
||||
|
|
|
@ -1,356 +0,0 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Utilities/RedtapeWindows.h"
|
||||
|
||||
#include "SamplProf.h"
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
DWORD GetModuleFromPtr(IN void* ptr,OUT LPWSTR lpFilename,IN DWORD nSize)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
VirtualQuery(ptr,&mbi,sizeof(mbi));
|
||||
return GetModuleFileName((HMODULE)mbi.AllocationBase,lpFilename,nSize);
|
||||
}
|
||||
|
||||
struct Module
|
||||
{
|
||||
uptr base;
|
||||
uptr end;
|
||||
uptr len;
|
||||
wxString name;
|
||||
u32 ticks;
|
||||
|
||||
Module(const wxChar* name, const void* ptr)
|
||||
{
|
||||
if (name!=0)
|
||||
this->name=name;
|
||||
FromAddress(ptr,name==0);
|
||||
ticks=0;
|
||||
}
|
||||
Module(const wxChar* name, const void* b, u32 s)
|
||||
{
|
||||
this->name=name;
|
||||
FromValues(b,s);
|
||||
ticks=0;
|
||||
}
|
||||
bool operator<(const Module &other) const
|
||||
{
|
||||
return ticks>other.ticks;
|
||||
}
|
||||
wxString ToString(u32 total_ticks)
|
||||
{
|
||||
return wxsFormat( L"| %s: %2.2f%% |", name.c_str(), (float)(((double)ticks*100.0) / (double)total_ticks) );
|
||||
}
|
||||
bool Inside(uptr val) { return val>=base && val<=end; }
|
||||
void FromAddress(const void* ptr,bool getname)
|
||||
{
|
||||
wxChar filename[512];
|
||||
wxChar filename2[512];
|
||||
static const void* ptr_old=0;
|
||||
|
||||
if (ptr_old==ptr)
|
||||
return;
|
||||
ptr_old=ptr;
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
VirtualQuery(ptr,&mbi,sizeof(mbi));
|
||||
base=(u32)mbi.AllocationBase;
|
||||
GetModuleFileName((HMODULE)mbi.AllocationBase,filename,512);
|
||||
len=(u8*)mbi.BaseAddress-(u8*)mbi.AllocationBase+mbi.RegionSize;
|
||||
|
||||
if (getname)
|
||||
{
|
||||
name=filename;
|
||||
size_t last=name.find_last_of('\\');
|
||||
last=last==name.npos?0:last+1;
|
||||
name=name.substr(last);
|
||||
}
|
||||
|
||||
for(;;)
|
||||
{
|
||||
VirtualQuery(((u8*)base)+len,&mbi,sizeof(mbi));
|
||||
if (!(mbi.Type&MEM_IMAGE))
|
||||
break;
|
||||
|
||||
if (!GetModuleFileName((HMODULE)mbi.AllocationBase,filename2,512))
|
||||
break;
|
||||
|
||||
if (wxStrcmp(filename,filename2)!=0)
|
||||
break;
|
||||
len+=mbi.RegionSize;
|
||||
}
|
||||
|
||||
|
||||
end=base+len-1;
|
||||
}
|
||||
void FromValues(const void* b,u32 s)
|
||||
{
|
||||
base= (uptr)b;
|
||||
len=s;
|
||||
end=base+len-1;
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<wxString,Module> MapType;
|
||||
|
||||
static std::vector<Module> ProfModules;
|
||||
static MapType ProfUnknownHash;
|
||||
|
||||
static HANDLE hEmuThread = NULL;
|
||||
static HANDLE hMtgsThread = NULL;
|
||||
static HANDLE hProfThread = NULL;
|
||||
|
||||
static CRITICAL_SECTION ProfModulesLock;
|
||||
|
||||
static volatile bool ProfRunning=false;
|
||||
|
||||
static bool _registeredName( const wxString& name )
|
||||
{
|
||||
for( std::vector<Module>::const_iterator
|
||||
iter = ProfModules.begin(),
|
||||
end = ProfModules.end(); iter<end; ++iter )
|
||||
{
|
||||
if( iter->name.compare( name ) == 0 )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProfilerRegisterSource(const wxString& Name, const void* buff, u32 sz)
|
||||
{
|
||||
if( ProfRunning )
|
||||
EnterCriticalSection( &ProfModulesLock );
|
||||
|
||||
if( !_registeredName( Name ) )
|
||||
ProfModules.push_back( Module( Name, buff, sz ) );
|
||||
|
||||
if( ProfRunning )
|
||||
LeaveCriticalSection( &ProfModulesLock );
|
||||
}
|
||||
|
||||
void ProfilerRegisterSource(const wxString& Name, const void* function)
|
||||
{
|
||||
if( ProfRunning )
|
||||
EnterCriticalSection( &ProfModulesLock );
|
||||
|
||||
if( !_registeredName( Name ) )
|
||||
ProfModules.push_back( Module(Name,function) );
|
||||
|
||||
if( ProfRunning )
|
||||
LeaveCriticalSection( &ProfModulesLock );
|
||||
}
|
||||
|
||||
void ProfilerRegisterSource(const char* Name, const void* buff, u32 sz)
|
||||
{
|
||||
ProfilerRegisterSource( fromUTF8(Name), buff, sz );
|
||||
}
|
||||
|
||||
void ProfilerRegisterSource(const char* Name, const void* function)
|
||||
{
|
||||
ProfilerRegisterSource( fromUTF8(Name), function );
|
||||
}
|
||||
|
||||
void ProfilerTerminateSource( const wxString& Name )
|
||||
{
|
||||
for( std::vector<Module>::const_iterator
|
||||
iter = ProfModules.begin(),
|
||||
end = ProfModules.end(); iter<end; ++iter )
|
||||
{
|
||||
if( iter->name.compare( Name ) == 0 )
|
||||
{
|
||||
ProfModules.erase( iter );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProfilerTerminateSource( const char* Name )
|
||||
{
|
||||
ProfilerTerminateSource( fromUTF8(Name) );
|
||||
}
|
||||
|
||||
static bool DispatchKnownModules( uint Eip )
|
||||
{
|
||||
bool retval = false;
|
||||
EnterCriticalSection( &ProfModulesLock );
|
||||
|
||||
size_t i;
|
||||
for(i=0;i<ProfModules.size();i++)
|
||||
if (ProfModules[i].Inside(Eip)) break;
|
||||
|
||||
if( i < ProfModules.size() )
|
||||
{
|
||||
ProfModules[i].ticks++;
|
||||
retval = true;
|
||||
}
|
||||
|
||||
LeaveCriticalSection( &ProfModulesLock );
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void MapUnknownSource( uint Eip )
|
||||
{
|
||||
wxChar modulename[512];
|
||||
DWORD sz=GetModuleFromPtr((void*)Eip,modulename,512);
|
||||
wxString modulenam( (sz==0) ? L"[Unknown]" : modulename );
|
||||
|
||||
std::map<wxString,Module>::iterator iter = ProfUnknownHash.find(modulenam);
|
||||
if (iter!=ProfUnknownHash.end())
|
||||
{
|
||||
iter->second.ticks++;
|
||||
return;
|
||||
}
|
||||
|
||||
Module tmp((sz==0) ? modulenam.wc_str() : NULL, (void*)Eip);
|
||||
tmp.ticks++;
|
||||
|
||||
ProfUnknownHash.insert(MapType::value_type(modulenam, tmp));
|
||||
}
|
||||
|
||||
int __stdcall ProfilerThread(void* nada)
|
||||
{
|
||||
ProfUnknownHash.clear();
|
||||
u32 tick_count=0;
|
||||
|
||||
while(ProfRunning)
|
||||
{
|
||||
Sleep(5);
|
||||
|
||||
if (tick_count>500)
|
||||
{
|
||||
wxString rT = L"";
|
||||
wxString rv = L"";
|
||||
u32 subtotal=0;
|
||||
for (size_t i=0;i<ProfModules.size();i++)
|
||||
{
|
||||
wxString t = ProfModules[i].ToString(tick_count);
|
||||
bool b0 = EmuConfig.Cpu.Recompiler.UseMicroVU0;
|
||||
bool b1 = EmuConfig.Cpu.Recompiler.UseMicroVU1;
|
||||
if ( b0 && b1) { if (t.Find(L"sVU") == -1) rT+=t;}
|
||||
else if (!b0 && !b1) { if (t.Find(L"mVU") == -1) rT+=t;}
|
||||
else if (!b0) { if (t.Find(L"mVU0") == -1) rT+=t;}
|
||||
else if (!b1) { if (t.Find(L"mVU1") == -1) rT+=t;}
|
||||
else rT+=t;
|
||||
|
||||
subtotal+=ProfModules[i].ticks;
|
||||
ProfModules[i].ticks=0;
|
||||
}
|
||||
|
||||
rT += wxsFormat( L"| Recs Total: %2.2f%% |", (float)(((double)subtotal*100.0) / (double)tick_count));
|
||||
std::vector<MapType::mapped_type> lst;
|
||||
for (MapType::iterator i=ProfUnknownHash.begin();i!=ProfUnknownHash.end();i++)
|
||||
{
|
||||
lst.push_back(i->second);
|
||||
}
|
||||
|
||||
sort(lst.begin(),lst.end());
|
||||
for (size_t i=0;i<lst.size();i++)
|
||||
{
|
||||
rv += lst[i].ToString(tick_count);
|
||||
}
|
||||
|
||||
Console.WriteLn( L"Sampling Profiler Results:\n%s\n%s\n", rT.c_str(), rv.c_str() );
|
||||
Console.SetTitle(rT);
|
||||
|
||||
tick_count=0;
|
||||
|
||||
ProfUnknownHash.clear();
|
||||
}
|
||||
|
||||
tick_count++;
|
||||
|
||||
CONTEXT ctx;
|
||||
ctx.ContextFlags = CONTEXT_FULL;
|
||||
GetThreadContext(hEmuThread,&ctx);
|
||||
|
||||
if( !DispatchKnownModules( ctx.Eip ) )
|
||||
{
|
||||
MapUnknownSource( ctx.Eip );
|
||||
}
|
||||
|
||||
if( hMtgsThread != NULL )
|
||||
{
|
||||
GetThreadContext(hMtgsThread,&ctx);
|
||||
if( DispatchKnownModules( ctx.Eip ) )
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ProfilerInit()
|
||||
{
|
||||
if (ProfRunning)
|
||||
return;
|
||||
|
||||
Console.WriteLn( "Profiler Thread Initializing..." );
|
||||
ProfRunning=true;
|
||||
DuplicateHandle(GetCurrentProcess(),
|
||||
GetCurrentThread(),
|
||||
GetCurrentProcess(),
|
||||
&(HANDLE)hEmuThread,
|
||||
0,
|
||||
FALSE,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
|
||||
InitializeCriticalSection( &ProfModulesLock );
|
||||
|
||||
hProfThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ProfilerThread,0,0,0);
|
||||
SetThreadPriority(hProfThread,THREAD_PRIORITY_HIGHEST);
|
||||
Console.WriteLn( "Profiler Thread Started!" );
|
||||
}
|
||||
|
||||
void ProfilerTerm()
|
||||
{
|
||||
Console.WriteLn( "Profiler Terminating..." );
|
||||
if (!ProfRunning)
|
||||
return;
|
||||
|
||||
ProfRunning=false;
|
||||
|
||||
if( hProfThread != NULL )
|
||||
{
|
||||
ResumeThread(hProfThread);
|
||||
WaitForSingleObject(hProfThread,INFINITE);
|
||||
CloseHandle(hProfThread);
|
||||
}
|
||||
|
||||
if( hEmuThread != NULL )
|
||||
CloseHandle( hEmuThread );
|
||||
|
||||
if( hMtgsThread != NULL )
|
||||
CloseHandle( hMtgsThread );
|
||||
|
||||
DeleteCriticalSection( &ProfModulesLock );
|
||||
Console.WriteLn( "Profiler Termination Done!" );
|
||||
}
|
||||
|
||||
void ProfilerSetEnabled(bool Enabled)
|
||||
{
|
||||
if (!ProfRunning)
|
||||
{
|
||||
if( !Enabled ) return;
|
||||
ProfilerInit();
|
||||
}
|
||||
|
||||
if (Enabled)
|
||||
ResumeThread(hProfThread);
|
||||
else
|
||||
SuspendThread(hProfThread);
|
||||
}
|
|
@ -203,7 +203,6 @@
|
|||
<ClCompile Include="..\..\Pcsx2Config.cpp" />
|
||||
<ClCompile Include="..\..\PluginManager.cpp" />
|
||||
<ClCompile Include="..\FlatFileReaderWindows.cpp" />
|
||||
<ClCompile Include="..\SamplProf.cpp" />
|
||||
<ClCompile Include="..\..\SaveState.cpp" />
|
||||
<ClCompile Include="..\..\SourceLog.cpp" />
|
||||
<ClCompile Include="..\..\System\SysCoreThread.cpp" />
|
||||
|
@ -456,7 +455,6 @@
|
|||
<ClInclude Include="..\..\IopCommon.h" />
|
||||
<ClInclude Include="..\..\NakedAsm.h" />
|
||||
<ClInclude Include="..\..\Plugins.h" />
|
||||
<ClInclude Include="..\..\SamplProf.h" />
|
||||
<ClInclude Include="..\..\SaveState.h" />
|
||||
<ClInclude Include="..\..\System.h" />
|
||||
<ClInclude Include="..\..\System\SysThreads.h" />
|
||||
|
|
|
@ -230,9 +230,6 @@
|
|||
<ClCompile Include="..\..\PluginManager.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\SamplProf.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\SaveState.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
|
@ -915,9 +912,6 @@
|
|||
<ClInclude Include="..\..\Plugins.h">
|
||||
<Filter>System\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\SamplProf.h">
|
||||
<Filter>System\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\SaveState.h">
|
||||
<Filter>System\Include</Filter>
|
||||
</ClInclude>
|
||||
|
|
Loading…
Reference in New Issue