View Full Version : How to measure execution time? And code size?
gnormhurst
08-02-2004, 21:09
Can someone describe a simple way to measure how much of the 26 ms time budget is being used? As I add code I would like to know how close I am coming to the limit.
Also, how do I know how close I am to the memory limits for code and data?
Thanks all,
Norm
Jay Lundy
09-02-2004, 04:03
Add a breakpoint at the top of process_data_from_master_uP and at the bottom. Then use the simulator and the stopwatch to calculate the time different between the 2 breakpoints.
For the memory thing, use the simulator and just look at the memory map of program and data memory.
Astronouth7303
09-02-2004, 07:32
What simulator? I tried one in mplab, and it got stuck in one of the transmission loops!
Chris Hibner
09-02-2004, 08:54
Can someone describe a simple way to measure how much of the 26 ms time budget is being used? As I add code I would like to know how close I am coming to the limit.
Also, how do I know how close I am to the memory limits for code and data?
Thanks all,
Norm
To measure the time, you should toggle a digital I/O pin every cycle. Then, hook an oscilliscope up to that pin. Using the scope, you can measure your timing very accurately.
Some example code (place this at the very beginning of your code):
static char TimingFlag;
if (TimingFlag)
TimingFlag = 0;
else
TimingFlag = 1;
Then immediately set the digital I/O pin equal to TimingFlag.
This code will produce a square wave on the scope. The time that the wave is high (or low) is your cycle time. I hope this helps.
-Chris
Mark McLeod
09-02-2004, 09:01
Can someone describe a simple way to measure how much of the 26 ms time budget is being used? As I add code I would like to know how close I am coming to the limit.
Also, how do I know how close I am to the memory limits for code and data?
Thanks all,
Norm
For the timing I set an internal timer and initialize the timer at the start and read it when it comes around again. You can use clock ticks or convert it to ms. I wouldn't use the MPLAB SIM for this.
For the default code you get 112,840 to 112,892 loops per second or ~42 (THE_ANSWER) ticks per loop for the basic default program (results may vary).
There are a couple of ways to check memory utilization.
1) When you open the .hex file in the IFI_Loader there is a text string at the bottom of the IFI_Loader window that tells you how much space the .hex file uses. For instance, the FRC default code will show:
"Total Bytes 2C90, Erase Size B5, Flash 800-3510, MemSize 2D10"
2)A memory map can be generated by MPLAB whenever you compile your code. You have to turn it on by going to Project -> Build Options... -> Project then click on the "MPLINK Linker" tab, then click on "Generater map file". After you build your project look in the project directory for a text file ending in ".map" just a little way down the file it will have a section that looks like:
Program Memory Usage
Start End
--------- ---------
0x000800 0x000837
0x0008d4 0x0033d8
0x0033da 0x003511
0x300000 0x30000d
11395 out of 33816 program addresses used, program memory utilization is 33%
This gives you the program or rom space used. For the data or ram space it's a little harder. After the section above all space used will be listed by address. You'll see your familiar variables listed. You have to check the maximum addresses used by the data portion of your code.
e.g.,
I 0x0007b7 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
count 0x0007b8 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
temp 0x0007b9 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
Alan Anderson
09-02-2004, 09:44
Also, how do I know how close I am to the memory limits for code and data?
The loader reports some information on program size. I'm not sure what it all means, but it's there.
What simulator? I tried one in mplab, and it got stuck in one of the transmission loops!Yeah, the simulator they have is fairly worthless.
KenWittlief
09-02-2004, 10:56
measureing timeing on the simulator wont tell you what you want to know, because the SW will be running on your PC, not on the target system (the RC) which is what really matters.
gnormhurst
09-02-2004, 11:10
measureing timeing on the simulator wont tell you what you want to know, because the SW will be running on your PC, not on the target system (the RC) which is what really matters.
I don't know squat about the Simulator, but I think Mr. Lundy may have been saying that the Simulator is "clock speed-aware". It may know, or can be told, what the processor's clock rate is. I guess if the code doesn't use interrupts, that would be enough to determine the number of processor clock cycles between two points in the code.
realExecutionTime = simulatedClockCycles * realClockPeriod
I'll have to have a closer look at the simulator. At this point I feel like I don't have time to go up another learning curve. But I should probably do it anyway...
Chris Hibner
09-02-2004, 11:33
To measure the time, you should toggle a digital I/O pin every cycle. Then, hook an oscilliscope up to that pin. Using the scope, you can measure your timing very accurately.
Some example code (place this at the very beginning of your code):
static char TimingFlag;
if (TimingFlag)
TimingFlag = 0;
else
TimingFlag = 1;
Then immediately set the digital I/O pin equal to TimingFlag.
This code will produce a square wave on the scope. The time that the wave is high (or low) is your cycle time. I hope this helps.
-Chris
Oh yeah, I forgot one thing.
My first post only works if you're running the loop time as fast as possible. It doesn't work if you're setting your loop time with an interrupt. To measure this way do the following:
1) At the VERY BEGINNING of your loop, set a digital I/O pin high.
2) At the VERY END of your loop, set the same digital I/O pin low.
3) Measure the pin voltage on a scope.
The amount of the the pin stays high is the amount of time that your code takes to run.
(By the way, this is how code time is usually measured in industry.)
gnormhurst
09-02-2004, 11:34
To measure the time, you should toggle a digital I/O pin every cycle. Then, hook an oscilliscope up to that pin. Using the scope, you can measure your timing very accurately.
Ooo, I like the idea of using a scope. Technology that I understand!
But I think the code you suggest may not give me what I want. I think the code you suggest would toggle a pin with every 26 ms cycle of the code, so the high and low portions of each square wave cycle would each be 26 ms, regardless of how long my code was taking.
Your code was:
static char TimingFlag;
if (TimingFlag)
TimingFlag = 0;
else
TimingFlag = 1;
// Then immediately set the digital I/O pin equal to TimingFlag.
How about this instead, in main.c. Note the two lines with ***:
while (1) /* This loop will repeat indefinitely. */
{
if (statusflag.NEW_SPI_DATA) /* 26.2ms loop area */
{ /* I'm slow! I only execute every 26.2ms because */
/* that's how fast the Master uP gives me data. */
rc_dig_out01 = 1; // *** look at this on a scope to see when loop starts
Process_Data_From_Master_uP(); /* You edit this in user_routines.c */
if (autonomous_mode) /* DO NOT CHANGE! */
{
User_Autonomous_Code(); /* You edit this in user_routines_fast.c */
}
}
Process_Data_From_Local_IO(); /* You edit this in user_routines_fast.c */
/* I'm fast! I execute during every loop.*/
rc_dig_out01 = 0; // *** look on scope to see how long it took!
} /* while (1) */
deltacoder1020
09-02-2004, 12:32
What simulator? I tried one in mplab, and it got stuck in one of the transmission loops!
remember that you have to have the constant "_SIMULATOR" defined while compiling code for the simulator - this keeps the program from bogging down in the transmission loop.
Jay Lundy
09-02-2004, 13:02
Yeah I didn't mean an actual stopwatch, there is a function in the simulator that keeps track of time based on chip speed. It's called the "stopwatch".
But the oscilloscope idea sounds easier (assuming you have an oscilloscope you can use).
[EDIT]Oops...
deltacoder1020
09-02-2004, 14:00
oscillator
i'm guessing you mean "oscilloscope". :)
KenWittlief
09-02-2004, 16:03
engineers have to learn to listen to what people mean, not what they say :)
Rickertsen2
09-02-2004, 18:28
Can someone describe a simple way to measure how much of the 26 ms time budget is being used? As I add code I would like to know how close I am coming to the limit.
Also, how do I know how close I am to the memory limits for code and data?
Thanks all,
Norm
I wouldn't worry too much about the 26 ms. If your code starts running over, then simply write some timer based code, that automatically sunchs w/the master provessor at least every 26ms. Use a backbuffering system, where you keep two copies of your data to send, a "im still working on this data" copy and a "this data is ready to send off" copy". You have a timer interrupt based function that is called every 25 ms or so that sends of the completed set of data automatically. When you have new data, you swap out the two sets. Take as much time as you want processign and don't worry about the 26ms. I would recommend you try to keep things under 26 ms, but if you can't then the above will work just fine. The way we measure the 26 ms time is by pulsing one of the IO lines each tiem data is sent off. That line is hooked up to a frequency counter. Thats the easiest wya if you have a frequency counter, or at the very least an oscilliscope.
A memory map can be generated by MPLAB whenever you compile your code. You have to turn it on by going to Project -> Build Options... -> Project then click on the "MPLINK Linker" tab, then click on "Generater map file". After you build your project look in the project directory for a text file ending in ".map" just a little way down the file it will have a section that looks like:
Program Memory Usage
Start End
--------- ---------
0x000800 0x000837
0x0008d4 0x0033d8
0x0033da 0x003511
0x300000 0x30000d
11395 out of 33816 program addresses used, program memory utilization is 33%
This gives you the program or rom space used. For the data or ram space it's a little harder. After the section above all space used will be listed by address. You'll see your familiar variables listed. You have to check the maximum addresses used by the data portion of your code.
e.g.,
I 0x0007b7 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
count 0x0007b8 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
temp 0x0007b9 data static C:\mcc18\Projects\FrcCode\FrcCode\ifi_library.c
Thanks for this info Mark! This is helpful. I've just been looking at the .map file for my latest build and trying to calculate how much RAM I'm using up. I looked in the .map file in the section where it's sorted by address and noticed something interesting:
Symbols - Sorted by Address
Name Address Location Storage File
--------- --------- --------- --------- ---------
__tmp_0 0x000000 data static D:\Code\Comp\v1\ifi_utilities.c
...
nullStr 0x0007da data extern D:\Code\Comp\v1\printf_lib.c
RCSTA2 0x000f6b data extern C:\FIRST\SRC\PROC\p18f8520.asm
...
TOSU 0x000fff data extern C:\FIRST\SRC\PROC\p18f8520.asm
I put the "..." in there to condense the info. But the interesting thing is the transition from C variables to assembly variables. The C variables occupy 2010 bytes of memory (0x000000 up to 0x0007da). Then there's a bunch of empty space from 0x0007db on up to 0x000f6a, and then the assembly variables occupy 0x000f6b up to 0x000fff. There are 4095 (FFF) bytes of RAM available in total, but it looks like all the IFI assembly defs and unions occupy the last 148 bytes from 0x000f6b up to 0x000fff.
To truly measure how many bytes you're using, you have to take the hex difference between the first assembly variable address (in all cases I think this will be 0x000f6b) and the last C variable address (in my case 0x0007da). Convert this number to decimal and subtract it from 4095 and the result is how many bytes of RAM your code uses.
It's also worth keeping in mind then that we really have 3946 bytes (up to 0x000f6a) of useable RAM since the IFI assembly stuff reserves the last 148 bytes. It will be hard to use that much RAM, but it's still worth noting.
Mark McLeod
17-02-2004, 08:06
Another interesting file to take a look at is "18f8520user.lkr"
It's a script for the linker blocking off PIC memory. A bunch of the space is listed as PROTECTED and the highest unprotected address is END=0x7F3
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.