Page 1 of 1
performance counter
Posted: Sun Apr 25, 2004 3:37 am
by Saotome
is there something (an assembler instruction) for the EE to get the count of processor-cycles since the last reset? something like the "rdtsc" instruction for pentium-processors. would be very usefull for optimizing.
thanks
Posted: Sun Apr 25, 2004 3:49 am
by blackdroid
You have timer registers that you can set up for a variety of ways to measure time, check out ps2perf from cvs.ps2dev.org for some more info or the EE user manual which describes the timer registers in detail.
Posted: Sun Apr 25, 2004 4:25 am
by Saotome
oh that should help, although it doesnt look as simple as the rdtsc ;)
thank you :)
Posted: Sun Apr 25, 2004 5:54 am
by blackdroid
its not as primitive as rdtsc thats right :)
Posted: Sun Apr 25, 2004 10:51 am
by mrbrown
Just use the COP0 Count register. It's the same as any other MIPS. The timer registers won't give you any cycle counts.
Posted: Sun Apr 25, 2004 7:38 pm
by blackdroid
doh thats right.
Posted: Thu May 06, 2004 6:33 am
by jenova0
Performance Counters can be accessed using the mfpc, mtpc, mfps, mtps instructions.
Posted: Sun Jul 11, 2004 12:28 pm
by evilo
Hi all,
could you elaborate on it ? I'm not so familiar with mips cpu, and I'm also trying to get that information... and didn't find yet ...
thank you !
Posted: Sun Jul 11, 2004 2:37 pm
by blackdroid
look at the source for ps2perf.
Posted: Sun Jul 11, 2004 8:43 pm
by evilo
thank you, just had a look, this is very interesting to make some probing when developing... ;)
anyway my need in fact is more on time related function, and more precisely like the gettimeofday() function & timeval struct... (the only thing I saw is sthg in the libcdvd library, but I also saw that it cannot be called too often (what of course I need to do... )
I'm trying to get a GetTicks() function, so that's why.... but seems difficult and the end ! anyone has any idea on this ?
Posted: Sun Jul 11, 2004 10:06 pm
by blackdroid
well set up the time mode register for whatever granularity you need, then getTicks ( or whatever you want to call it ) to read the time count register.
Unless by "ticks" you mean cycles, and in that case we are back to reading the performance counters.
Posted: Mon Jul 12, 2004 7:49 am
by evilo
So, If I use event0Select(EV0_ProcessorCycle), it should do the job ?
Posted: Mon Jul 12, 2004 7:57 am
by Drakonite
What exactly are you needing it for? There might be a better combination of things to accomplish what you want, but I'm kinda confused what exactly you need.
Posted: Mon Jul 12, 2004 6:32 pm
by evilo
well, at the start, I was looking to time function, as I need to calculate the elapsed time in second between two events.
I found out that the current clock can be retreived in the cd/dvd module, BUT also read that it cannot be done to often....
SO, as I didn't find them, I was thinking to estimate it based on processor cycles and it's frequence ...
Posted: Mon Jul 12, 2004 9:12 pm
by blackdroid
if the granularity is seconds just set the timer registers to count vertical blanks. divide by 50 or 60 depending on pal vs ntsc mode.
Posted: Mon Jul 12, 2004 9:58 pm
by evilo
not a bad idea...
thanks for the tip !
Posted: Tue Jul 13, 2004 6:52 am
by Drakonite
If you are only calling once per frame then you can query the clock no problem.
Posted: Tue Jul 13, 2004 8:47 am
by mrbrown
Drakonite wrote:If you are only calling once per frame then you can query the clock no problem.
If you're referring to the RTC then this is a very bad idea. I would hate to give a single function 300ms per frame just to return a 60th of a second. As others have suggested using the EE's timer to count up seconds is the best solution (after reading the RTC once).
Posted: Tue Jul 13, 2004 8:58 am
by Drakonite
300ms? oi. I knew it was bad but didn't think it was that bad.
Posted: Tue Jul 13, 2004 2:03 pm
by J.F.
The RTC is in the CDROM controller. You do a CD call with the IOP to get it. Therefore, it's DAMN slow! It's usually only called when the program starts to get the time. The program then uses timers, the vertical blank, or the performance counters to keep track of time after that.
Posted: Wed Jul 14, 2004 3:21 am
by mrbrown
As always, thank you J.F. for a consise summary of the thread.
Posted: Wed Jul 14, 2004 5:06 am
by hermes
Hi
I add this code if you want to use a timer by interruptions. In this case it is adjust to steps of 2ms and it use the frequency of the bus how clock.
If you need examples that activate threads by interruptions, i have some examples in ps2reality.net ( but they are in Spanish language)
Code: Select all
//////////////////////////////////////////////////////////////////////////////////////
// SYSCALLS NECESSARY
//////////////////////////////////////////////////////////////////////////////////////
int H_EnableIntcHandler(int inter)
{
DI;
__asm __volatile__(" addiu $3, $0, 0x0014
syscall
nop");
EI;
}
int H_DisableIntcHandler(int inter)
{
DI;
__asm __volatile__(" addiu $3, $0, 0x0015
syscall
nop");
EI;
}
// LIST OF ID FOR INTERRUPTS
enum
{
INT_GS,
INT_SBUS,
INT_VBLANK_START,
INT_VBLANK_END,
INT_VIF0,
INT_VIF1,
INT_VU0,
INT_VU1,
INT_IPU,
INT_TIMER0,
INT_TIMER1
};
//////////////////////////////////////////////////////////////////////////////////////
// REGISTERS FOR TIMERS
//////////////////////////////////////////////////////////////////////////////////////
// timer T0
#define T0_COUNT *((volatile unsigned long*)0x10000000)
#define T0_MODE *((volatile unsigned long*)0x10000010)
#define T0_COMP *((volatile unsigned long*)0x10000020)
#define T0_HOLD *((volatile unsigned long*)0x10000030)
// timer T1
#define T1_COUNT *((volatile unsigned long*)0x10000800)
#define T1_MODE *((volatile unsigned long*)0x10000810)
#define T1_COMP *((volatile unsigned long*)0x10000820)
#define T1_HOLD *((volatile unsigned long*)0x10000830)
unsigned count_time=0;
//////////////////////////////////////////////////////////////////////////////////////
// interrupt handler
//////////////////////////////////////////////////////////////////////////////////////
int handlerItim(int ca)
{
count_time+=2; // count in steps of 2 ms
T0_MODE|=1024; // enable next interrupt
return -1; // only this handler
}
#define TIME_MS 2.0
#define CLOCK_BUS 147456.0
int id_TIM; // id handler
main()
{
unsigned count_time2;
T0_MODE=0; // disable timer
id_TIM=AddIntcHandler(INT_TIMER0,handlerItim,0); // set handler
H_EnableIntcHandler(INT_TIMER0); // enable handler
count_time=0; // counter
T0_COMP=(unsigned) (TIME_MS/(256.0/CLOCK_BUS)); // adjust comparator to 2 ms
T0_COUNT=0; // counter at zero
T0_MODE=256+128+64+2; // set mode to clock=BUSCLK/256, reset to 0,count and interrupt if comparator equal...
//start code
// .......
// end code
count_time2=count_time;
T0_MODE=0; // disable timer
H_DisableIntcHandler(INT_TIMER0); // disable handler
RemoveIntcHandler(INT_TIMER0,id_TIM); // kill handler
printf("last time: %u\n",count_time2);
SleepThread();
}