AnsweredHot!PIC32MZ large array causing slow boot

Author
junlez
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2017/08/04 11:25:43
  • Location: 0
  • Status: offline
2018/10/10 12:23:36 (permalink)
0

PIC32MZ large array causing slow boot

Hi,
 
We are using a PIC32MZ2048EFM100 running @36MHz. I statically allocated a very large array to use as our main buffer via:
#define MEMBUFLEN (1024*448)
char __attribute__((coherent, aligned(4))) memBuffer[MEMBUFLEN];

This seems to slow down reset-to-code execution time considerably, around 600ms @36MHz, 300ms @72MHz. When I decrease MEMBUFLEN from (1024*448) to (1024*8), the boot time is near instantaneous and the problem is fixed.
 
What is the cause for this? Is there any way around this slow boot up process?
 
Thanks and best,
Junle
 
#1
qhb
Superb Member
  • Total Posts : 7159
  • Reward points : 0
  • Joined: 2016/06/05 14:55:32
  • Location: One step ahead...
  • Status: online
Re: PIC32MZ large array causing slow boot 2018/10/10 12:26:27 (permalink) ☼ Best Answerby junlez 2018/10/11 10:47:52
0
The run time will be clearing all that memory on startup.
I think if you declare it as "persistent" it will stop doing that. Then of course you cannot make any assumptions about its contents on startup.
 

Worst forum problems are now fixed, but the damn firewall is still there.
#2
junlez
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2017/08/04 11:25:43
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/10 12:35:23 (permalink)
0
This did indeed solve it! Thanks qhb!
Does it really take 600ms @36MHz to clear 448kB of RAM? The buffer is in KSEG1 from the coherent attribute, so caching is off, but still, 600ms is a bit long no?
 
#3
Larry.Standage
Super Member
  • Total Posts : 839
  • Reward points : 0
  • Joined: 2011/12/30 09:50:47
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/10 13:35:07 (permalink) ☄ Helpfulby junlez 2018/10/11 10:47:58
0
Without looking at the startup code, we'll look at just writing one byte to each memory location, since you've defined it as a char.
Each write will be a complete bus access (instead of a cached one), and each write to SRAM takes about 7 clocks. At 36 MHz, 448 * 1024 writes will take 89ms alone. That doesn't count the additional instructions for the loop that the processor will have to execute. So 600ms actually sounds about right.
 
Since the persistent attribute took care of the startup, perhaps you're not looking for additional ideas. But here are a few anyway:
  • 36 MHz is an unusual speed. Can you start up at 200 MHz, then drop the speed down after startup?
  • 32-bit writes would cut the startup time by a considerable amount. Could you declare the array as an array of words, then use a byte pointer that points to the same location?
  • If you need the array to start with 0s, you could use the DMA to fill the array.
 
 
 
#4
Jim Nickerson
User 452
  • Total Posts : 5280
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 06:27:38 (permalink)
0
I wonder if the time changes in Release versus Debug mode ?
[Edit] Howard's answer below would indicate NO
post edited by Jim Nickerson - 2018/10/11 08:16:40
#5
Howard Long
Super Member
  • Total Posts : 410
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: online
Re: PIC32MZ large array causing slow boot 2018/10/11 08:10:00 (permalink)
5 (1)
A quick look at the startup code reveals that the uninitialised bss section is cleared before initialising the cache "since the _bss_end symbol may not be cache-line aligned":
 

 
##################################################################
# Clear uninitialized data sections
##################################################################
_start_bss_init:
la t0,_bss_begin
la t1,_bss_end
b _bss_check
nop
 
_bss_init:
sw zero,0x0(t0)
sw zero,0x4(t0)
sw zero,0x8(t0)
sw zero,0xc(t0)
addu t0,16
_bss_check:
bltu t0,t1,_bss_init
nop
 
#if defined(INIT_L1_CACHE) || defined(__PIC32_HAS_L1CACHE)
##################################################################
# Initialize L1 cache. This must be done after bss clearing
# since the _bss_end symbol may not be cache-line aligned.
##################################################################
.extern __pic32_init_cache
la t0,__pic32_init_cache
jalr t0
nop
#endif
 

post edited by Howard Long - 2018/10/11 08:11:30
#6
Howard Long
Super Member
  • Total Posts : 410
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: online
Re: PIC32MZ large array causing slow boot 2018/10/11 08:39:16 (permalink)
0
Also note that the startup code doesn't initialise the PCACHE, wait states or prefetch.
#7
junlez
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2017/08/04 11:25:43
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 11:19:11 (permalink)
0
Larry.Standage
  • 36 MHz is an unusual speed. Can you start up at 200 MHz, then drop the speed down after startup?
  • 32-bit writes would cut the startup time by a considerable amount. Could you declare the array as an array of words, then use a byte pointer that points to the same location?
  • If you need the array to start with 0s, you could use the DMA to fill the array.

Thanks for the suggestions Larry, the data in the array does not need to be initialized to 0, so the persist flag works just fine :) Out of curiosity, I did change the array type to int and the startup time is still around 600ms. This kind of makes sense since if the PIC is clearing the declared RAM section, it probably clears the entire chunk with 32-bit operations? But that is still very slow memory clearing. From Howard's code, it seems like the assembly code is pretty straight forward, I wonder why it takes the PIC so long to zero out the RAM.
 
@Howard, where did you find this startup code? I did a search through the MPLAB directory and only found .o files containing the text. Where did you find the source code for this?
 
Thanks for all the help guys.
#8
andersm
Super Member
  • Total Posts : 2466
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 11:37:09 (permalink)
0
Unpack pic32-libs/pic32m-libs.zip, then look in pic32m-libs/libpic32/startup.
#9
junlez
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2017/08/04 11:25:43
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 12:08:20 (permalink)
0
Awesome, thanks!
 
Still surprised that clearing 448 kB of RAM takes 600ms @ 36 MHz, any ideas as to why?
 
post edited by junlez - 2018/10/11 12:09:53
#10
andersm
Super Member
  • Total Posts : 2466
  • Reward points : 0
  • Joined: 2012/10/07 14:57:44
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 13:26:22 (permalink)
0
Verify that you're actually running at the speed you think you are. After boot, you're also running with prefetch disabled and max wait states, and as mentioned earlier in the thread, the L1 cache hasn't been enabled yet.
#11
junlez
New Member
  • Total Posts : 7
  • Reward points : 0
  • Joined: 2017/08/04 11:25:43
  • Location: 0
  • Status: offline
Re: PIC32MZ large array causing slow boot 2018/10/11 14:13:06 (permalink)
0
Ah I see, makes a lot more sense now, because a while ago, I did measure how long it took to memset zero-out 1 kB of data and I remember it being quite fast.
 
Thanks for the clarifications.
#12
Jump to:
© 2018 APG vNext Commercial Version 4.5