EmbeddedRelated.com
Forums
Memfault Beyond the Launch

evaluation of boot execution time

Started by alb November 10, 2014
Hi everyone,

I'm trying to understand how much time it takes for my system to boot 
and I define 'booting' as the process from 'cpu reset' to begin of 
execution of my 'main' program (if a better definition for this phase 
exists I'd be happy if somebody can point it out to me).

I'm simulating my embedded processor on an RTL simulator and I report 
a note when the instruction memory port is loaded with the 
instruction 'brlid' to 'main address' (in my case brlid r15, 1784).

So now I have my 'booting' time but I sense I'm missing something. For 
instance, I'd believe that if the type of program is /different/ the 
amount of time it takes to boot would be /different/.

Is there any standard way to measure the booting time? Any idea on how 
to instrument my program in order to see what affects booting time?

Thanks a lot for any suggestions/ideas/comments.

Al

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Op Mon, 10 Nov 2014 09:58:17 +0100 schreef alb <al.basili@gmail.com>:
> I'm trying to understand how much time it takes for my system to boot
Then read the boot code. :)
> and I define 'booting' as the process from 'cpu reset' to begin of > execution of my 'main' program (if a better definition for this phase > exists I'd be happy if somebody can point it out to me). > > I'm simulating my embedded processor on an RTL simulator and I report > a note when the instruction memory port is loaded with the > instruction 'brlid' to 'main address' (in my case brlid r15, 1784). > > So now I have my 'booting' time but I sense I'm missing something. For > instance, I'd believe that if the type of program is /different/ the > amount of time it takes to boot would be /different/.
If the boot code is the same then the time could be the same. If the boot code distinguishes between cold and warm boots, that might cause differences.
> Is there any standard way to measure the booting time?
If your simulator has a cycle counter, then I would recommend using that.
> Any idea on how > to instrument my program in order to see what affects booting time?
Instrument the boot code! -- (Remove the obvious prefix to reply privately.) Gemaakt met Opera's e-mailprogramma: http://www.opera.com/mail/
Hi Boudewijn,

Boudewijn Dijkstra <sp4mtr4p.boudewijn@indes.com> wrote:
[]
>> I'm trying to understand how much time it takes for my system to boot > > Then read the boot code. :)
sure even though I do not believe it is the most efficient way to get this type of information.
>> and I define 'booting' as the process from 'cpu reset' to begin of >> execution of my 'main' program (if a better definition for this phase >> exists I'd be happy if somebody can point it out to me). >> >> I'm simulating my embedded processor on an RTL simulator and I report >> a note when the instruction memory port is loaded with the >> instruction 'brlid' to 'main address' (in my case brlid r15, 1784). >> >> So now I have my 'booting' time but I sense I'm missing something. For >> instance, I'd believe that if the type of program is /different/ the >> amount of time it takes to boot would be /different/. > > If the boot code is the same then the time could be the same. If the boot > code distinguishes between cold and warm boots, that might cause > differences.
Ok, maybe I should have given more information about the environment. The boot code, as defined, is essentially taken by the C run time environment to setup bss, heap, stack and whatever else is needed for the program to run, with necessary calls to .ctors as needed. I do not see any cold or warm boots, only the length of data sections which might be different and take more time to configure. Do I miss anything else? []
>> Any idea on how >> to instrument my program in order to see what affects booting time? > > Instrument the boot code!
Why should I instrument the boot code? I would like to see, given the current library, what elements of my program have an impact on the execution time of the booting phase. If I instrument the current library I will not obtain what I want. Al
Op Mon, 10 Nov 2014 12:21:55 +0100 schreef alb <al.basili@gmail.com>:
> Boudewijn Dijkstra <sp4mtr4p.boudewijn@indes.com> wrote: > [] >>> I'm trying to understand how much time it takes for my system to boot >> >> Then read the boot code. :) > > sure even though I do not believe it is the most efficient way to get > this type of information.
It is a good way to learn about the internals of embedded systems.
>>> and I define 'booting' as the process from 'cpu reset' to begin of >>> execution of my 'main' program (if a better definition for this phase >>> exists I'd be happy if somebody can point it out to me). >>> >>> I'm simulating my embedded processor on an RTL simulator and I report >>> a note when the instruction memory port is loaded with the >>> instruction 'brlid' to 'main address' (in my case brlid r15, 1784). >>> >>> So now I have my 'booting' time but I sense I'm missing something. For >>> instance, I'd believe that if the type of program is /different/ the >>> amount of time it takes to boot would be /different/. >> >> If the boot code is the same then the time could be the same. If the >> boot >> code distinguishes between cold and warm boots, that might cause >> differences. > > Ok, maybe I should have given more information about the environment. > The boot code, as defined, is essentially taken by the C run time > environment to setup bss, heap, stack and whatever else is needed for > the program to run, with necessary calls to .ctors as needed.
So, you are specifically interested in the "cstartup" part of the boot process. Your linker should be able to tell you the sizes of bss, heap, stack, etc. Setting up .bss and .data should be linear with size. Setting up stack and heap could be negligible or linear with size depending on whether they are filled with a pattern.
> I do not see any cold or warm boots, only the length of data sections > which might be different and take more time to configure. Do I miss > anything else? > > [] >>> Any idea on how >>> to instrument my program in order to see what affects booting time? >> >> Instrument the boot code! > > Why should I instrument the boot code? I would like to see, given the > current library, what elements of my program have an impact on the > execution time of the booting phase. If I instrument the current library > I will not obtain what I want.
Indeed, cstartup is pretty straightforward. However, it is not inconceivable that your toolchain inserts hardware initialisation routines depending on the needs of the program. -- (Remove the obvious prefix to reply privately.) Gemaakt met Opera's e-mailprogramma: http://www.opera.com/mail/
Hi Boudewijn,

Boudewijn Dijkstra <sp4mtr4p.boudewijn@indes.com> wrote:
[]
>>> Then read the boot code. :) >> >> sure even though I do not believe it is the most efficient way to get >> this type of information. > > It is a good way to learn about the internals of embedded systems.
Ok I did read the assembler and the basic structure is the following: start | +-> crtinit | | | + configure bss | + program_init | + main | + fini | + program_clean +-> exit the 'configure bss' should be something like this: 128: 20c04738 addi r6, r0, 18232 // 4738 <_SDA_BASE_> 12c: 20e04738 addi r7, r0, 18232 // 4738 <_SDA_BASE_> 130: 06463800 rsub r18, r6, r7 134: bc720014 blei r18, 20 // 148 138: f8060000 swi r0, r6, 0 13c: 20c60004 addi r6, r6, 4 140: 06463800 rsub r18, r6, r7 144: bc92fff4 bgti r18, -12 // 138 148: 20c04738 addi r6, r0, 18232 // 4738 <_SDA_BASE_> 14c: 20e04790 addi r7, r0, 18320 // 4790 <__bss_end> 150: 06463800 rsub r18, r6, r7 154: bc720014 blei r18, 20 // 168 158: f8060000 swi r0, r6, 0 15c: 20c60004 addi r6, r6, 4 160: 06463800 rsub r18, r6, r7 164: bc92fff4 bgti r18, -12 // 158 []
>> Ok, maybe I should have given more information about the environment. >> The boot code, as defined, is essentially taken by the C run time >> environment to setup bss, heap, stack and whatever else is needed for >> the program to run, with necessary calls to .ctors as needed. > > So, you are specifically interested in the "cstartup" part of the boot > process.
I didn't know it was called 'cstartup', I've always heard about crtinit instead.
> Your linker should be able to tell you the sizes of bss, heap, > stack, etc. Setting up .bss and .data should be linear with size. > Setting up stack and heap could be negligible or linear with size > depending on whether they are filled with a pattern.
AFAIK .data is initialized and is included in the binary file so it shouldn't really contribute to boot time. .bss on the contrary shall be initialized to '0' and does contribute to booting time. []
>> Why should I instrument the boot code? I would like to see, given the >> current library, what elements of my program have an impact on the >> execution time of the booting phase. If I instrument the current library >> I will not obtain what I want. > > Indeed, cstartup is pretty straightforward. However, it is not > inconceivable that your toolchain inserts hardware initialisation routines > depending on the needs of the program.
Uhm, I'm using a mb-gcc on an MB-lite architecture, I haven't seen, thus far, any particular nuances related to hardware initialization. Al
Op Mon, 10 Nov 2014 14:39:35 +0100 schreef alb <al.basili@gmail.com>:
> Boudewijn Dijkstra <sp4mtr4p.boudewijn@indes.com> wrote: > [] >> So, you are specifically interested in the "cstartup" part of the boot >> process. > > I didn't know it was called 'cstartup', I've always heard about crtinit > instead.
I guess it depends which toolchain pedigree you are most familiar with. ;)
>> Your linker should be able to tell you the sizes of bss, heap, >> stack, etc. Setting up .bss and .data should be linear with size. >> Setting up stack and heap could be negligible or linear with size >> depending on whether they are filled with a pattern. > > AFAIK .data is initialized and is included in the binary file so it > shouldn't really contribute to boot time.
That depends on whether your data is in volatile storage on reset. If the initial values are in Flash, then they need to be copied to RAM first.
> .bss on the contrary shall be > initialized to '0' and does contribute to booting time.
Indeed. -- (Remove the obvious prefix to reply privately.) Gemaakt met Opera's e-mailprogramma: http://www.opera.com/mail/
Hi Boudewijn,

Boudewijn Dijkstra <sp4mtr4p.boudewijn@indes.com> wrote:
[]
>> I didn't know it was called 'cstartup', I've always heard about crtinit >> instead. > > I guess it depends which toolchain pedigree you are most familiar with. ;)
always used GNU toolchain. Does it exists another one??? ;-) []
>> AFAIK .data is initialized and is included in the binary file so it >> shouldn't really contribute to boot time. > > That depends on whether your data is in volatile storage on reset. If the > initial values are in Flash, then they need to be copied to RAM first.
you have a point. This step is done by the FPGA fabric so when the processor is started everything is happily residing in RAM. Al
Hi Al,

On 11/10/2014 1:58 AM, alb wrote:
> I'm trying to understand how much time it takes for my system to boot > and I define 'booting' as the process from 'cpu reset' to begin of > execution of my 'main' program (if a better definition for this phase > exists I'd be happy if somebody can point it out to me).
Then, have main() tickle a GPIO and measure the time from the release of RESET to the time you see that GPIO tickled. Note that you haven't discussed your environment so it's unclear whether this time will be constant (given no changes to your executable) OR highly variable! E.g., if your startup code contains initialization routines that have to "make the hardware safe" and the hardware's state can vary from one RESET to the next, then the time required to reinitialize it can vary. This can also be true in other cases. E.g., imagine you had to count restarts and store the result in FLASH... what happens if *this* FLASH write needs to be retried while the FLASH write for the previous restart didn't? Or, if the write requires an ERASE cycle, etc.?
> I'm simulating my embedded processor on an RTL simulator and I report > a note when the instruction memory port is loaded with the > instruction 'brlid' to 'main address' (in my case brlid r15, 1784). > > So now I have my 'booting' time but I sense I'm missing something. For > instance, I'd believe that if the type of program is /different/ the > amount of time it takes to boot would be /different/.
Define "different"...
> Is there any standard way to measure the booting time? Any idea on how > to instrument my program in order to see what affects booting time? > > Thanks a lot for any suggestions/ideas/comments.
Only you (thinking on behalf of your customer/user) can decide what a MEANINGFULL measurement would be. E.g., if the first line of main() gets executed within a dozen microseconds of RESET being released... BUT, main spends the first three minutes doing other housekeeping BEFORE the user can effectively *use* your device, then the 12 usec time is stupid! E.g., that's the trick desktop apps use to throw up a splash screen QUICKLY so you think they are "already running" when, in fact, they have a bunch of initialization code that still has to execute before they can be USED!
Hi Don,

Don Y <this@is.not.me.com> wrote:
>> I'm trying to understand how much time it takes for my system to boot >> and I define 'booting' as the process from 'cpu reset' to begin of >> execution of my 'main' program (if a better definition for this phase >> exists I'd be happy if somebody can point it out to me). > > Then, have main() tickle a GPIO and measure the time from the release > of RESET to the time you see that GPIO tickled.
I do a similar thing but in simulation and I spy on the instruction bus when the 'jump to main' instruction is executed.
> > Note that you haven't discussed your environment so it's unclear > whether this time will be constant (given no changes to your executable) > OR highly variable!
That is the biggest issue I have. Unfortunately the requirements are quite misleading here since there's a total lack of 'perimeter' for the code and we need to provide the hardware. So our nice customer has been encouraged to believe that they can make an algorithm in Matlab, export it as C and compile it for our architecture (MB-Lite) without breaking a sweat! I believe this lack of coordination will lead to no joy at all! Sob.
> E.g., if your startup code contains initialization routines that have > to "make the hardware safe" and the hardware's state can vary from one > RESET to the next, then the time required to reinitialize it can vary.
Fortunately this is not the case. The hardware is configured by the FPGA in the 'safe mode' and the software doesn't need to perform any of such operations.
> This can also be true in other cases. E.g., imagine you had to count > restarts and store the result in FLASH... what happens if *this* > FLASH write needs to be retried while the FLASH write for the previous > restart didn't? Or, if the write requires an ERASE cycle, etc.?
Sure, I must admit my OP wasn't at all clear w.r.t. boundary conditions.
>> I'm simulating my embedded processor on an RTL simulator and I report >> a note when the instruction memory port is loaded with the >> instruction 'brlid' to 'main address' (in my case brlid r15, 1784). >> >> So now I have my 'booting' time but I sense I'm missing something. For >> instance, I'd believe that if the type of program is /different/ the >> amount of time it takes to boot would be /different/. > > Define "different"...
Assume I have program A and program B, both of them accomplishing the same task but written differently. A uses lots of global variables while B doesn't use them. All statically allocated objects, like global variables, need to be configured at run-time and will eat up my booting time. In what aspect can A and B differ more that would have an impact on booting time? []
> E.g., that's the trick desktop apps use to throw up a splash screen > QUICKLY so you think they are "already running" when, in fact, they > have a bunch of initialization code that still has to execute before > they can be USED!
I see your point, but we are far from emulating this sick trend. My measurement would be from RESET to operational, where the operational is really when the main starts. Al
Hi Al,

On 11/11/2014 7:20 AM, alb wrote:
>>> I'm simulating my embedded processor on an RTL simulator and I report >>> a note when the instruction memory port is loaded with the >>> instruction 'brlid' to 'main address' (in my case brlid r15, 1784). >>> >>> So now I have my 'booting' time but I sense I'm missing something. For >>> instance, I'd believe that if the type of program is /different/ the >>> amount of time it takes to boot would be /different/. >> >> Define "different"... > > Assume I have program A and program B, both of them accomplishing the > same task but written differently. A uses lots of global variables while > B doesn't use them. > > All statically allocated objects, like global variables, need to be > configured at run-time and will eat up my booting time. In what aspect > can A and B differ more that would have an impact on booting time?
You are essentially saying all hardware related issues are "off the table" and just looking at software issues? You could write A to be incredibly inefficient at *whatever* it does. While this sounds pedantic, it may actually *not* be! I know of a piece of production code that stored all of it's data as ASCII numeric strings. This made configuration relatively easy. And, you could visually inspect the data to verify the results (instead of having to CORRECTLY decode a multibyte binary value and verify *that*!) Unfortunately, in real terms, this meant the processor spent gobs of time in sscanf(3c). And, used a COTS library for all this stuff despite the fact that their use was far from typical! When profiled, the results were so dramatic that they were convinced it was a "measurement error": "Shirley the processor can't be spending ALL it's time in sscanf!" ("Yes, it is! And stop calling me Shirley!") Any other sorts of coding practice that don't nicely fit with the expectations of your environment (hardware, OS, etc.) can also dramatically increase execution time. E.g., poor locality of reference can dramatically impact the efficacy of any caches. VM systems can be crippled by inconsiderate choices of algorithms ("for all i do {for all j do { something with x[i][j] } }" behaves differently from "for all j do {for all i do { something with x[i][j] } }" First, assess how competent folks are with the tools/environment in which they are tasked with working. If they are aware of these sorts of issues, then they will adapt before (or after) they encounter a big performance hit. In any case, you may want to consider policies or mechanisms that remove much of the "bad choices" from your implementation -- *if* the results are viable! (e.g., don't allow VM if it's not likely to be used properly)
>> E.g., that's the trick desktop apps use to throw up a splash screen >> QUICKLY so you think they are "already running" when, in fact, they >> have a bunch of initialization code that still has to execute before >> they can be USED! > > I see your point, but we are far from emulating this sick trend. My > measurement would be from RESET to operational, where the operational is > really when the main starts.
People tend to be notoriously ignorant of where time is spent in algorithms (e.g., the sscanf() example). And, too often "prematurely optimize" -- often NEVER having obtained empirical data AND considered how that data would likely change "in the wild". Assumptions are the root of all errors and inefficiencies. People *think* they know what is happening under the hood but, in reality, are just making GUESSES based on their own personal biases. A better approach is to "do the math" (i.e., a calculator instead of a Quija board!) Set some criteria for your "boot time". Something that your client/customer can agree to. And, something that you can *measure* (think like a lawyer -- or a Test Technician!). Make sure folks know the RELATIVE significance of this up front so they can factor it into their design methodology. (I say *relative* because you can end up with pathological implementations where folks do silly things to make ONE criteria look artificially "good" at the expense of other, potentially more significant, criteria!)

Memfault Beyond the Launch