performance counter

Discuss the development of software, tools, libraries and anything else that helps make ps2dev happen.

Moderators: cheriff, Herben

Post Reply
User avatar
Saotome
Posts: 182
Joined: Sat Apr 03, 2004 3:45 am

performance counter

Post 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
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post 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.
Kung VU
User avatar
Saotome
Posts: 182
Joined: Sat Apr 03, 2004 3:45 am

Post by Saotome »

oh that should help, although it doesnt look as simple as the rdtsc ;)
thank you :)
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post by blackdroid »

its not as primitive as rdtsc thats right :)
Kung VU
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post 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.
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post by blackdroid »

doh thats right.
Kung VU
jenova0
Posts: 2
Joined: Thu May 06, 2004 6:26 am
Location: Toronto, ON, CA
Contact:

Post by jenova0 »

Performance Counters can be accessed using the mfpc, mtpc, mfps, mtps instructions.
User avatar
evilo
Posts: 230
Joined: Thu Apr 22, 2004 8:40 pm
Contact:

Post 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 !
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post by blackdroid »

look at the source for ps2perf.
Kung VU
User avatar
evilo
Posts: 230
Joined: Thu Apr 22, 2004 8:40 pm
Contact:

Post 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 ?
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post 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.
Kung VU
User avatar
evilo
Posts: 230
Joined: Thu Apr 22, 2004 8:40 pm
Contact:

Post by evilo »

So, If I use event0Select(EV0_ProcessorCycle), it should do the job ?
User avatar
Drakonite
Site Admin
Posts: 990
Joined: Sat Jan 17, 2004 1:30 am
Contact:

Post 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.
Shoot Pixels Not People!
Makeshift Development
User avatar
evilo
Posts: 230
Joined: Thu Apr 22, 2004 8:40 pm
Contact:

Post 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 ...
blackdroid
Posts: 564
Joined: Sat Jan 17, 2004 10:22 am
Location: Sweden
Contact:

Post 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.
Kung VU
User avatar
evilo
Posts: 230
Joined: Thu Apr 22, 2004 8:40 pm
Contact:

Post by evilo »

not a bad idea...

thanks for the tip !
User avatar
Drakonite
Site Admin
Posts: 990
Joined: Sat Jan 17, 2004 1:30 am
Contact:

Post by Drakonite »

If you are only calling once per frame then you can query the clock no problem.
Shoot Pixels Not People!
Makeshift Development
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post 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).
User avatar
Drakonite
Site Admin
Posts: 990
Joined: Sat Jan 17, 2004 1:30 am
Contact:

Post by Drakonite »

300ms? oi. I knew it was bad but didn't think it was that bad.
Shoot Pixels Not People!
Makeshift Development
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post 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.
mrbrown
Site Admin
Posts: 1537
Joined: Sat Jan 17, 2004 11:24 am

Post by mrbrown »

As always, thank you J.F. for a consise summary of the thread.
hermes
Posts: 25
Joined: Tue Mar 30, 2004 5:22 am
Location: Spain

Post 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();
}
Post Reply