openxc / vi-firmware

OpenXC-compatible firmware for PIC32 and LPC1768
http://vi-firmware.openxcplatform.com
BSD 3-Clause "New" or "Revised" License
198 stars 106 forks source link

Benchmark all queue sizes to identify optimal size #162

Closed peplin closed 11 years ago

peplin commented 11 years ago

I think some of the in-memory queues are grossly oversized right now, adding to the statically allocated memory pressure. As a first pass before changing to dynamic allocation, I want to get an idea of the appropriate sizes. The buffers in question:

peplin commented 11 years ago

I added queue length logging for the CanBus receive and send queues in 8d91ecf. I noticed it's always zero, and with further investigation found that the only time we ever stress the queue is in short bursts. We would need a queue of ~200 messages to handle this example burst. If we allocate that it's around 25KB, which will likely be tough with 32KB of RAM. I'm not sure what do do about this.

peplin commented 11 years ago

I've added queue size logging for the USB, UART and network queues - they are never more than 3% used on average, so we can save some space there.

tgiuli commented 11 years ago

Wow, a 200 message burst -- not to be obsessive, but could you plot the queue size vs time? Do you have a sense of whether the burst occurs on the CAN bus, or if in this case the MCU is busy parsing other messages and so incoming CAN messages accumulate over time in the buffer without being serviced?

peplin commented 11 years ago

I'll obviously want to spend a little more time on it to make sure but what I saw today could be graphed like this:

                  |           FULL FULL FULL            FULL FULL FULL
Queue Size        |
                  |
                  |   0 0 0 0                0 0 0 0 0 
                  |____________________________________________

                                              Time

We're spinning through the main loop no sweat, usually no more than 1 CAN message is queued up to be processed so I can hardly even register anything being in the queue unless I record in exactly the right spot until BAM, the CAN interrupt handler just takes over with 150+ messages in a row.

peplin commented 11 years ago

I've decreased the size of the send/receive queues for the 3 output interfaces and added an alternative process mechanism to make sure we don't overflow the buffer (in a8843d0). The code size went from:

> arm-none-eabi-size build/FORDBOARD/vi-firmware-FORDBOARD.elf 
   text    data     bss     dec     hex filename
 132120   19112    4828  156060   2619c build/FORDBOARD/vi-firmware-FORDBOARD.elf

to

> arm-none-eabi-size build/FORDBOARD/vi-firmware-FORDBOARD.elf
   text    data     bss     dec     hex filename
 132216   15528    4828  152572   253fc build/FORDBOARD/vi-firmware-FORDBOARD.elf

a savings of 3.5KB of RAM.

peplin commented 11 years ago

Moving a PIC32-only buffer to the PIC32 build only dropped from:

   text    data     bss     dec     hex filename
 130752   12312    4724  147788   2414c build/FORDBOARD/vi-firmware-FORDBOARD.elf

to

   text    data     bss     dec     hex filename
 130752   11800    4724  147276   23f4c build/FORDBOARD/vi-firmware-FORDBOARD.elf

another 512 bytes of RAM. The PIC32 has 128KB of RAM so I don't think this will make the builds lopsided.

peplin commented 11 years ago

Make the CanSignalState array a const array dropped it again (in 60ff054):

   text    data     bss     dec     hex filename
 132528   15240    4868  152636   2543c build/FORDBOARD/vi-firmware-FORDBOARD.elf

to

   text    data     bss     dec     hex filename
 135120   12648    4868  152636   2543c build/FORDBOARD/vi-firmware-FORDBOARD.elf

saving 2.5KB (this is now the C-Max build, that's why the overall size is a bit larger than the previous comments which were with the Flex 2011).

peplin commented 11 years ago

We're down to these top RAM hogs:

> arm-none-eabi-nm build/FORDBOARD/vi-firmware-FORDBOARD.elf --size-sort | grep " D "
<truncated...>
00000200 D iso_buffer
00000200 D usb_data_buffer
00000200 D usb_data_buffer_IN
00000200 D usb_data_buffer_OUT
0000032c D USB_DEVICE
00000408 D __malloc_av_
00000804 D SIGNALS
000010a0 D CAN_BUSES
peplin commented 11 years ago

After optimizing some types, the new totals:

> arm-none-eabi-nm build/FORDBOARD/vi-firmware-FORDBOARD.elf --size-sort | grep " D "
<truncated...>
00000200 D iso_buffer
00000200 D usb_data_buffer
00000200 D usb_data_buffer_IN
00000200 D usb_data_buffer_OUT
00000320 D USB_DEVICE
00000408 D __malloc_av_
0000072c D SIGNALS
000010a0 D CAN_BUSES

taking it from:

> arm-none-eabi-size build/FORDBOARD/vi-firmware-FORDBOARD.elf
   text    data     bss     dec     hex filename
 135120   12648    4868  152636   2543c build/FORDBOARD/vi-firmware-FORDBOARD.elf

to

   text    data     bss     dec     hex filename
 135128   12408    4868  152404   25354 build/FORDBOARD/vi-firmware-FORDBOARD.elf

for a savings of 240 bytes (CanSignal structs are down to 68 bytes each from 76).

peplin commented 11 years ago

I'll split off a new issue re: optimizing the CAN message queues and close this one as I'm happy with the space savings. For the C-Max 2013 build, at the start we had:

> arm-none-eabi-size build/FORDBOARD/vi-firmware-FORDBOARD.elf
   text    data     bss     dec     hex filename
 132272   19472    4844  156588   263ac build/FORDBOARD/vi-firmware-FORDBOARD.elf

and now in the next branch we have:

> arm-none-eabi-size build/FORDBOARD/vi-firmware-FORDBOARD.elf
   text    data     bss     dec     hex filename
 135128   12408    4868  152404   25354 build/FORDBOARD/vi-firmware-FORDBOARD.elf