Занимаюсь проектом - запуск x86 Windows программ на планшетнике под Windows RT. Нужно было найти наиболее "тормозящие" места в коде, а Visual Studio 2012 не имеет в себе профайлера для АРМ, там даже profile-guided optimization падает на более-менее больших объемах кода. В итоге пришлось в очередной раз писать свой профайлер. Раньше уже раза 3 делал такой же код, еще под Windows Mobile в порте QEMU, и как на зло - код нигде не сохранился.
Поэтому оставляю код тут, на будущее :)
Код - прост до ужаса. Параллельный поток останавливает интересующий нас поток программы, получает его PC и фиксирует сколько раз на этом месте мы были. Далее - в отладчике стопорим программу, ставим DumpProfiler=true, сортируем/фильтруем полученный лог в Excel-е по адресам - и анализируем в отладчике что где за функция вызывалась.
mamaich, 27.01.2013
Поэтому оставляю код тут, на будущее :)
CSet Counters;
bool volatile DumpProfiler=false;
bool ForEachFunc(unsigned int Idx, void *Data, void *Param)
{
if(Data)
LogInfo("%08X - %d\n",Idx,Data);
return true;
}
HANDLE ProfThread=0;
DWORD WINAPI Profiler(
_In_ LPVOID lpParameter
)
{
CONTEXT Ctx;
while(1)
{
SuspendThread(ProfThread);
Ctx.ContextFlags=CONTEXT_CONTROL;
GetThreadContext(ProfThread,&Ctx);
ResumeThread(ProfThread);
Counters.Set(Ctx.Pc,(void*)(1+(DWORD)Counters.Get(Ctx.Pc)));
if(DumpProfiler)
{
Counters.ForEach(ForEachFunc,0);
}
Sleep(20);
}
}
void InitProfiler()
{
DuplicateHandle(GetCurrentProcess(),GetCurrentThread(),GetCurrentProcess(),&ProfThread,0,FALSE,DUPLICATE_SAME_ACCESS);
CreateThread(0,0,Profiler,0,0,0);
}
Код - прост до ужаса. Параллельный поток останавливает интересующий нас поток программы, получает его PC и фиксирует сколько раз на этом месте мы были. Далее - в отладчике стопорим программу, ставим DumpProfiler=true, сортируем/фильтруем полученный лог в Excel-е по адресам - и анализируем в отладчике что где за функция вызывалась.
mamaich, 27.01.2013
Комментариев нет:
Отправить комментарий