First of All, I should thank everybody who made PSPLink which is so great tool to help PSP development.
I tried gprof to debug my application in PSP. Unfortunately, the memory is not enough to support gprof in an application which already use almost all the memory. And gprof need recompile the application which I don't really want to do. So I am thinking to add sampling based profiler into psplink.
I want to start this thread to get the help and also report the status to public.
Overall Design
===========
I will use the forth channel of PSPLink to pass the sampling data realtime to the PC side. A PC side application will store the data into a file. Then we can use some high level language like python or perl to parse the file.
The data we can collect will be 1. PC value 2. time VBL interrupt happen 3. thread switch. I feel we can generate several reports based on these information.
Current Status:
==========
Investigate the file format to choose.
[Update: I will try to use cpu profiling file format from google perf-tool. So that we can leverage their resource.]
Complete the prototype which can use psplink's another channel.
[Update: it compiled and I receive the data.]
Issues need help:
============
1. which is the best way to do the sampling? Can I use sceSTimerSetHandler (concern its overhead.)? Or how can I use hardware interrupt?
2. How to read PC when interrupt happened? Should I find the active thread and read the thread context? Or there is faster way to do it.
3. Is there a good way to get the call stack (PC calling chain)? unwind.h is not useful in this case. We need some other way. Or we don't have a way in MIPS.
Profiler for PSPLink
Profiler for PSPLink
Last edited by howard0su on Mon Jan 12, 2009 6:25 pm, edited 1 time in total.
It all depends how often you are going to need to do the sampling. One thing you have to be careful of is you won't be able to send data over USB inside an interrupt context, i.e. inside a VBL or Timer handler which run outside of the current thread context. Therefore it might be simplest to just have a high priority thread running in the kernel which is calling sceKernelDelayThread :)
That said you probably want to queue events up anyway for performance reasons which means you could in those situations just use the thread purely for sending but it could be logged from anywhere. I haven't actually used the Stimer stuff but it is probably as low overhead as you are going to get without causing serious pain. VBL stuff is probably simply done using a vblank interrupt handler.
As for getting the PC, well yah thread context is probably the easiest and fastest way to do it. You might have to play with which PC you want as if the current thread is sitting in a kernel function it won't be that useful a metric. Look at how the thbp command works in psplink source.
Sounds an interesting project if you can get it to work :)
That said you probably want to queue events up anyway for performance reasons which means you could in those situations just use the thread purely for sending but it could be logged from anywhere. I haven't actually used the Stimer stuff but it is probably as low overhead as you are going to get without causing serious pain. VBL stuff is probably simply done using a vblank interrupt handler.
As for getting the PC, well yah thread context is probably the easiest and fastest way to do it. You might have to play with which PC you want as if the current thread is sitting in a kernel function it won't be that useful a metric. Look at how the thbp command works in psplink source.
Sounds an interesting project if you can get it to work :)
-
- Posts: 53
- Joined: Thu Mar 20, 2008 2:33 am
Code: Select all
sceKernelRegisterSubIntrHandler(30 /*VSYNC*/, 0, &your_handler, ...);
sceKernelEnableSubIntr(30, 0);
-
- Posts: 53
- Joined: Thu Mar 20, 2008 2:33 am
tnx hlide, but I meant how to find real vblank's interrupt address
i.e. address of VblankIntrHandler wich was registred with
in display.prx
i.e. address of VblankIntrHandler wich was registred with
Code: Select all
sceKernelRegisterIntrHandler(0x1E, 1, VblankIntrHandler, NULL, *IntrHandlerArgs);
howard0su: Are you not going to have to potentially walk the thread list anyway even if you hooked an exception to catch EPC directly as you probably want to know which thread was actually running at the time.
Tbh it all depends what you are trying to achieve, if it is a user mode profiler then I would say just add a thread monitor to catch new threads appearing and look up the context for each thread _once_.
Then when ever you timer goes off walk all the thread context blocks and get EPC.
Tbh it all depends what you are trying to achieve, if it is a user mode profiler then I would say just add a thread monitor to catch new threads appearing and look up the context for each thread _once_.
Then when ever you timer goes off walk all the thread context blocks and get EPC.