English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 17 October 2019, 16:39   #1
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Using a CIA to measure elapsed time

I'm trying to get some accurate time readings so I can measure where my code is spending it's time.

I've read the HRM, but I obviously don't understand it as my code doesn't work.

I'm trying to use CIAB Timer B to read the time at the start and end of a function:

Code:
volatile struct CIA * ciab = (struct CIA *) 0xbfd000;

void Profiler_Init(void) {
    ciab->ciatblo = 0;
    ciab->ciatbhi = 0;
    ciab->ciacrb = CIACRBF_START | CIACRBF_LOAD;
}

UWORD Profiler_GetCurrentTime(void) {
    UBYTE hi = ciab->ciatbhi;
    UBYTE lo = ciab->ciatblo;
    return ((UWORD) hi) << 8 | lo;
}
I call Profiler_Init after I take over the system.

Calls to Profiler_GetCurrentTime just return 0.

Any hints?

EDIT:

Found this thread, http://eab.abime.net/showthread.php?t=79734, I'm now getting values out. Still not sure I know what I'm doing though.

Last edited by deimos; 17 October 2019 at 17:24.
deimos is offline  
Old 17 October 2019, 17:39   #2
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,364
I don't remember all off the top of my head, but here's some tips and stuff I've run into when using the CIA's.

The thing that caused me some errors when I first did a CIA timer routine was that the timers count down and not up, so they should be initialized above zero (I used $FFFF). The other thing I got wrong is the order in which you do things matters. IIRC, you should first set the cra/crb bits and only then write to the counter register to start the timer.

I don't have access to LHA here, but there is a working counter example of a hardware banging CIA timer in my audio mixing cycle test code (found here: http://powerprograms.nl/resources/audio_mixing.lha - cycletest.asm). It's in assembly, but might still help.

One final note here is that the OS when it runs can in fact also use the timers, which may cause unexpected results. So if the OS is running, it's best to use OS functions for timing.

Edit: also note that manually banging the CIA registers can cause the keyboard to break, so you might have to store the previous values and restore them afterwards. This too is done in my example.

Last edited by roondar; 17 October 2019 at 17:46.
roondar is offline  
Old 17 October 2019, 17:40   #3
Spec-Chum
Registered User

 
Join Date: Dec 2016
Location: England
Posts: 85
I suspected it might have something to do with CIAICRF_TB, and this led me here: http://eab.abime.net/showthread.php?t=69903

Seems theirs works.

Hope this helps.
Spec-Chum is offline  
Old 17 October 2019, 18:12   #4
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Thank you roondar and Spec-Chum.
deimos is offline  
Old 17 October 2019, 18:18   #5
Spec-Chum
Registered User

 
Join Date: Dec 2016
Location: England
Posts: 85
Quote:
Originally Posted by deimos View Post
Still not sure I know what I'm doing though.
Welcome to programming
Spec-Chum is offline  
Old 17 October 2019, 18:28   #6
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,364
Personally I find the link to some parts of the physical hardware the hardest to understand properly. I can get most of the custom chips, but when it's about how to read or write to disk, or why reading a second joystick button requires special code to give the hardware time to respond I tend to get bamboozled

Doesn't help that the CIA's are different from the rest of the hardware - they were originally designed for Commodore's 8-bit machines (or perhaps more accurately, the Amiga CIA chips are very closely based on the 8-bit CIA's from the C64 etc - not sure if they're exactly the same chip though). Which means programming them is different from any other custom chip.
roondar is offline  
Old 17 October 2019, 19:04   #7
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,173
How about use CIA-B TOD? Granularity is 64us and counts up to 24bit.

My code:
http://eab.abime.net/showpost.php?p=1199574&postcount=1

@roondar: yes, CIA is a bit alien in Amiga architecture.
Being a former C64 coder helped me
ross is online now  
Old 17 October 2019, 19:28   #8
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Quote:
Originally Posted by ross View Post
How about use CIA-B TOD? Granularity is 64us and counts up to 24bit.

My code:
http://eab.abime.net/showpost.php?p=1199574&postcount=1

@roondar: yes, CIA is a bit alien in Amiga architecture.
Being a former C64 coder helped me
What does a granularity of 64us mean in context? Maths is hard, and I need as fine a time resolution as possible as I'd like to measure function calls in place without artificially changing my code.
deimos is offline  
Old 17 October 2019, 19:37   #9
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,173
Quote:
Originally Posted by deimos View Post
What does a granularity of 64us mean in context? Maths is hard, and I need as fine a time resolution as possible as I'd like to measure function calls in place without artificially changing my code.
Maths in not hard at all. You have simply counters to compare.

In Timer-A/B cases 1,41us granularity, max 92ms before a roll-up and count down.
In TOD-B case 64us granularity, max 1074s before a roll-up and count up.

Make a choice

EDIT: actually if you want you can also link Timer-A and B.

Last edited by ross; 17 October 2019 at 19:45.
ross is online now  
Old 17 October 2019, 19:52   #10
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Quote:
Originally Posted by ross View Post
Maths in not hard at all. You have simply counters to compare.

In Timer-A/B cases 1,41us granularity, max 92ms before a roll-up and count down.
In TOD-B case 64us granularity, max 1074s before a roll-up and count up.

Make a choice

EDIT: actually if you want you can also link Timer-A and B.
I think I need to get a few timings first before deciding. I have no idea whether the things I'm timing fit in 92ms. I just have no concept of that time.
deimos is offline  
Old 17 October 2019, 19:55   #11
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,173
Quote:
Originally Posted by deimos View Post
I think I need to get a few timings first before deciding. I have no idea whether the things I'm timing fit in 92ms. I just have no concept of that time.
A video frame at 50FPS is 20ms.

if the routines you need to be timed last many scanlines (>>20) better TOD else normal Timers.
ross is online now  
Old 17 October 2019, 20:20   #12
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,173
The simplest ever CIA-B Timer B counter code:


Code:
	lea	$bfd000,a5
	move.b	#8,$f00(a5)
	st	$600(a5)
	st	$700(a5)


	bsr	.your_code_to_be_timed

	sf	$f00(a5)
	move.b	$700(a5),d0
	lsl.w	#8,d0
	move.b	$600(a5),d0
	not.w	d0
d0*1,409683681078803e-6 for secs in PAL mode
ross is online now  
Old 17 October 2019, 20:41   #13
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Quote:
Originally Posted by ross View Post
The simplest ever CIA-B Timer B counter code:


Code:
	lea	$bfd000,a5
	move.b	#8,$f00(a5)
	st	$600(a5)
	st	$700(a5)


	bsr	.your_code_to_be_timed

	sf	$f00(a5)
	move.b	$700(a5),d0
	lsl.w	#8,d0
	move.b	$600(a5),d0
	not.w	d0
d0*1,409683681078803e-6 for secs in PAL mode
You start and stop the time around the bit of code you're timing. If that's the way it's supposed to be done, then perhaps I can't use it, as I want to time functions that are called from within functions that are also being timed. Can I pause and restart the time to take a snapshot, using it in continuous mode so that it wraps around without stopping?
deimos is offline  
Old 17 October 2019, 21:00   #14
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,173
Quote:
Originally Posted by deimos View Post
You start and stop the time around the bit of code you're timing. If that's the way it's supposed to be done, then perhaps I can't use it, as I want to time functions that are called from within functions that are also being timed. Can I pause and restart the time to take a snapshot, using it in continuous mode so that it wraps around without stopping?
Of course yes.
A
move.b #1,$f00(a5) 
restart the timer in continuous mode.

Is up to you to handle a possible roll-up.
But if the case much better a different approach (like with TOD).

Nothing in any case prevents you from using the different timers simultaneously.
ross is online now  
Old 17 October 2019, 22:48   #15
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 441
Ok, using TOD turned out to be the easiest way, and I needed the longer times it can do without making things more difficult. Right now I think the resolution is enough, and I'm getting some numbers out:

Code:
Frames generated: 63
Frames displayed: 62
Frames discarded: 1
Run time:         30680 ms
Frame rate:       2 fps

Function Name	Number of Calls	Total Elapsed Time
PlayGame	1	30897
Blitter_AquireBlit	16064	851
Renderer_TransformModel	63	1591
Renderer_RenderModel	63	28892
RenderFace	1558	24261
ClipAndFillPolygon2D	1558	21811
I just need to take a minute to work out what they mean.
deimos is offline  
Old 28 October 2019, 15:56   #16
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 50
Posts: 64
When I'm doing performance timings, I usually use clock() which is more then sufficient. If not, I just wrap the code in a loop and time that. Of course assuming you are using a C compiler.

i.E.
clock_t start = clock();
do my stuff;
clock_t elapsed = clock() - start;
sparhawk is offline  
Old 28 October 2019, 21:34   #17
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,479
clock() is difficult to implement under AmigaOS. IIRC, it should only measure the time spent in the current process. So depending on the clib used this might be more or less correct.
phx is offline  
Old 29 October 2019, 14:35   #18
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 50
Posts: 64
I never found this to be a problem, because when you repeat the test a few times, you get a good tendency how fast the code is. Even if there is something running in the background, it doesn't matter much, as long as this is running more or less stable.
It depends of course, if you need exact timing, because you need the code to run in an exact timeframe, or if you just want to improve the code to run faster. If you need an exact timing, then of course this method is not appropriate.
sparhawk is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Amiga joystick on pc for xyz time, but this time with adapter? :) Srksi support.WinUAE 3 24 May 2018 04:57
example of a CIA timer interrupt in assembler using cia.resource Apollo Coders. Asm / Hardware 3 05 July 2013 09:40
REQ:ASM getting elapsed time on A1200 jman Coders. Tutorials 18 11 January 2011 23:24
App to update Amiga System time from web time?? DDNI request.Apps 2 31 December 2007 08:21
CIA test Toni Wilen Coders. General 13 03 March 2007 23:14

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 23:24.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.
Page generated in 0.08920 seconds with 13 queries