DATASHEET SEARCH SITE | WWW.ALLDATASHEET.COM
Document overview
- Manufacturer or author: Provided By ALLDATASHEET.COM(FREE DATASHEET DOWNLOAD SITE)
- PDF pages: 28
Technical content
Rev. 0.1 9/12 Copyright © 2012 by Silicon Laboratories AN720 AN720 PRECISION 32™ O PTIMIZATION C ONSIDERATIONS FOR CODE S IZE AND S PEED 1. Introduction The code size and execution speed of a 32-bit MCU proj ect can vary greatly depending on the way the code is written, the toolchain libraries used, and the compiler and linker options. This document addresses how to determine what portions of code are taking extra space or time and ways to optimize for space or speed for different tool chains, including GCC redlib and newlib (Precision32 IDE) and Keil. 2. Key Points The key topics of this document are: How to determine what portions of the project are taking the most space Ways to benchmark code execution speed Common strategies to reduce code size or improve execution speed Code startup time and ways to reduce it 3. Using CoreMark™ as a Speed Benchmark CoreMark is a standard code base t hat can be ported to various processo rs to provide a speed benchmark. The CoreMark software provides a score that rates how fast the core and code is, providing a relative comparison between various toolchain options and settings. The CoreMa rk software package cannot be modified except for device-specific information in the portme files. For modes that do not support printf (nohosting libraries), the results were calculated using the value of the variable in code. See the CoreMark website for more information on the test and score reporting requirements (www.coremark.org). 4. Non-Toolchain Considerations The coding style and technique can have a great effect on the overall size of the project. 4.1. Coding Techniques There are many ways coding technique can affect code size, including library calls, inline code or data, or code optimizations made for global variables or pointers. For more information on writing C code for ARM architectures, see the following resources: EETimes - Energy efficient C code for ARM devices by Chris Shore: http://www.eetimes.com/design/ embedded/4210470/Efficient-C-Code-for-ARM-Devices Compiler Coding Practices - ARM: http://infocenter.arm.com/help/index.jsp?topic=/ com.arm.doc.dui0472c/CJAFJCFG.html These guidelines will largely apply regardless of the compiler used for the project. 4.2. Number of Function Parameters Functions with either Keil or GCC can have as many parame ters as desired. In general, the first four parameters are passed to the function efficiently using registers. Any additional parameters beyond four must be moved on or off the stack, which results in extra code size for each additional parameter and ex tra time to execute those instructions. If possible, keeping functions to no more than four parameters can help reduce code size and execution time.
2 Rev. 0.1 4.3. Alignment In most cases, Cortex-M3 linkers place code in memory ef ficiently. In some projects, however, the alignment of functions and code can be carefully managed manually to reduce code size or change code execution speed. For example, if two functions in the same file call each other, but one ends up in flash and one ends up in RAM, the compiler may need to place extra code to perform a long jump and take longer to execute that jump. If needed, functions and variables can be explicitly located using sc atterfiles and linker flags. More informat ion on linker scripts and scatterfiles can be found on the Code Red (http://support.code-red-tech.com/CodeRedWiki/ armlink_babddhbf.htm). 4.4. RAM Size The RAM size of a project can be just as important as th e code size. In particular, the default configurations for SiM3xxxx projects place the stack at the top of memory growing down and the heap at the end of program data growing up. If too much of the RAM is used by program data, then the stack and heap may collide, leading to difficult debugging issues in run-time. Projects shou ld always leave enough RAM space to accommodate the function-calling depth of the code. 4.5. SiM3xxxx Core and Flash Access Speed At the maximum device AHB speed, an SiM3xxxx device reading flash every pipeline cycle may violate the maximum flash access speed. To compen sate for this, the FLASHCTRL module has controls to reduce the flash access speed (SPMD and RDSEN). Depending on the code density and make-up (i.e., 16-bit or 32-bit instructions), this may lead to stalls in the core before the next instructions can be fetched from flash. Executing at high speeds with strings of 16-bit instructions may yield the fastest core operation. 4.6. SiM3xxxx Core and the Direct Memory Access (DMA) Module On SiM3xxxx devices, the core and the DMA can access multiple AHB slaves at the same time without any performance degradation. If the core and DMA access the same AHB slave at the same time (i.e., RAM), then the AHB has priority-based arbitration in the following precedence: 1. Core data fetch 2. DMA 3. Core instruction fetch If multiple DMA channels are active at the same time and accessing the same memory areas as the core, this could lead to a reduction in core execution speed.
- Precision32 IDE (redlib and newlib)
This section discusses ways to optimize projects using the Precision32 IDE and both redlib an d newlib libraries. with newlib v1.19 and Redlib v2 (Precision32 IDE v4.2.1 [Build 73]). memory. This map file is located in the build files for a project. excerpt of the sim3u1xx_Blinky redlib Debug example map file. my_rtc_alarm0_handler function starts at address 0x0000_04D4 and occupies 0x70 bytes of memory. Figure 1. sim3u1xx_Blinky Precision32 Debug Map File Example effective way to reduce code space.
- Right-click on the project_name in the Project Explorer view.
- In the C/C++ BuildSettingsBuild Steps tab, remove or add the following in the Post-build
Figure 2. Automatically Reporting Project Size on Project Build in Precision32
toolchains have no standard I/O capability (i.e., no printf()). opening the myLinkerOptions_p32.ld file in the project directory and changing the uncommented line. Figure 3. Using the myLinkerOptions_p32.ld File to Select the Project Library
- Left-click on the project_name in the Project Explorer view.
- Click on C/C++ BuildSettingsTool Settings tabMCU LinkerTarget and select the desired
library from the Use C library drop-down menu. Figure 4 shows this dialog in the Precision32 IDE.
- Clean and Build the project.
AppBuilder projects do not have a myLinkerOptions_P32.ld file and can use the Quickstart view setting only.
Figure 4. Using the Precision32 IDE to Select the Project Library For the newlib and redlib none libraries, see “5.4. Function Library Usage”. Table 1. Precision32 Toolchain Library Usage Comparison—sim3u1xx_Blinky Debug
Table 2. Precision32 Toolchain Library Usage Comparison—demo_si32UsbAudio Debug Table 3. Precision32 Toolchain Library Usage Comparison—CoreMark Debug Size Table 4. Precision32 Toolchain Library Usage Comparison—CoreMark Debug Speed
8 Rev. 0.1 5.4. Function Library Usage Function libraries such as floating point math and printf() can significantly increase the size of a project. If a project is constrained by size, a careful analysis of the usa ge of these large libraries may be required. For example, floating point can often be approximated well by fixe d point math, eliminating the need for the floating point libraries. The printf() library is often needed by projects for debugging or release code. If printf() is used for debugging purposes, using a defined symbol in the project to remove printf() when compiling a release build can dramatically reduce the size of a project. To define a symbol to di fferentiate between a Debug pr oject and a Release project, see “ Contact Information”. The code can then use #ifdef...#endif preprocessor statements to remove debugging code or printf() calls. The removal of debugging printf() statements can dramatically reduce the co de size of a project. A simple way to do this is to redefine the printf function at the top of the file containing the printf() calls using the following statement: #define printf(args...) For si32Library examples such as demo_si32UsbAudio, define the statement at the top of myBuildOptions.h to remove all calls to printf() with higher optimization settings. Additionally, reduce the code size footprint by disabling logging in myBuildOptions.h: #define si32BuildOption_enable_logging 0 This method preserves the printf() statements for later use, if needed. The printf() define can also be encapsulated with preprocessor #if statements to automatically include th is define when building with a Release configuration. When removing printf() for use with newlib none or re dlib none, all references to printf() and stdio.h must be commented out of the project. The none libraries cannot be used with si32Library projects. To verify that all instances of printf() have been removed, search the map file for the project for the printf library. In the sim3u1xx_Blinky example, this means adding the statement to both the main.c and gCpu.c files. Instead of using standard printf(), which can have a high library cost, use integer-only print functions like iprintf() for newlib projects. For redlib projects in the Precision32 IDE, create a define CR_INTEGER_PRINTF in the project properties to force an integer-only version of printf(). For instances of printf() with a fixed-string, using puts() can dramatically reduce code size. More information about redlib and printf() can be found on the Code Red website: http://support.code-red- tech.com/CodeRedWiki/UsingPrintf. If a project does not use any standard I/O functions, use the redlib or newlib none toolchain option to reduce code size as discussed in “6.3. Toolchain Library Usage”. Using the sim3u1xx_Blinky default example in the si32HAL 1.0.1 so ftware package, Table 5 shows the relative build sizes with the different printf() settings. The demo_si32UsbAudio comparison is not included since printf() removal requires higher optimization se ttings or code modifications. This section also does not include the CoreMark tests since printf is not part of the CoreMark benchmark.
Table 5. Precision32 printf() Comparison—sim3u1xx_Blinky Debug
Figure 6. Selecting the Active Build Configuration in the Precision32 IDE
- Right-click on the project_name in the Project Explorer view.
- In the C/C++ BuildSettingsTool Settings tab options, select the build configuration at the top and
the desired build configuration options. the CoreMark Debug build sizes, and Table 9 lists the CoreMark speed scores for these optimization levels.
Table 6. Precision32 Toolchain Optimization Comparison—sim3u1xx_Blinky Debug Table 7. Precision32 Toolchain Optimization Comparison—demo_si32UsbAudio Debug Table 8. Precision32 Toolchain Optimization Comparison—CoreMark Debug Size
Table 9. Precision32 Toolchain Optimization Comparison—CoreMark Debug Speed
Removed (unused) functions can be viewed in the map files for the projects.
- Right-click on the file_name in the Project Explorer view.
Figure 7. Modifying the Remove Unused Code Compiler Flags in the Precision32 IDE benefit in some cases, and may cause larger code size and slower execution in some cases. scores for the different unused code removal settings.
Table 10. Precision32 Unused Code Removal Comparison—sim3u1xx_Blinky Debug Table 11. Precision32 Unused Code Removal Comparison—demo_si32UsbAudio Debug Table 12. Precision32 Unused Code Removal Comparison—CoreMark Debug Size Table 13. Precision32 Unused Code Removal Comparison—CoreMark Debug Speed
SiM3C1xx that require a reset to exit the lowest power mode. memory of the device. This involves copying data from flash to RAM and zero-filling any zero-initialized segments. Then, the reset code typically calls a system initialization function and jumps to main. always be compiled with the fastest speed optimization to ensure it takes as little time as possible. si32HalOption_disable_pin_reset_delay symbol in the project.
- Right-click on the project_name in the Project Explorer view.
- In the C/C++ BuildSettingsTool Settings tabMCU C CompilerSettings options, add or
remove the symbol to the Defined symbols (-D) area. Figure 8. Adding a Project Define Symbol in the Precision32 IDE pin at the beginning of the Reset IRQ handler to the fall of a port pin at the beginning of main() on an oscilloscope. This test requires modification of the si32HAL startup sequence file startup_<device>_p32.c.
Table 14. Precision32 Toolchain Library Usage Comparison—sim3u1xx_Blinky Debug Reset
Table 16. Keil Toolchain Library Usage Comparison—demo_si32UsbAudio Debug Table 17. Keil Toolchain Library Usage Comparison—CoreMark Debug Size Table 18. Keil Toolchain Library Usage Comparison—CoreMark Debug Speed
the sim3u1xx_Blinky example, this means adding the statement to both the main.c and gCpu.c files. the CoreMark tests since printf is not part of the CoreMark benchmark. Table 19. Keil printf() Comparison—sim3u1x x_Blinky Debug Table 20. Keil printf() Comparison—demo_si32UsbAudio Debug
Table 21. Keil Toolchain Optimization Comparison—sim3u1xx_Blinky Debug Table 22. Keil Toolchain Optimization Comparison—demo_si32UsbAudio Debug
Table 23. Keil Toolchain Optimization Comparison—CoreMark Debug Size Table 24. Keil Toolchain Optimization Comparison—CoreMark Debug Speed
Removed (unused) functions can be viewed in the map files for the projects.
- Right-click on the project_name in the Project window and select Options for Target ‘project_name’ or
Options for Target ‘project_name’.
- Use the One ELF Section per Function checkbox to enable or disable unused code removal.
Figure 12. Setting the Remove Unused Code Option in the µVision IDE
Table 25. Keil Unused Code Removal Comparison—sim3u1xx_Blinky Debug Table 26. Keil Unused Code Removal Comparison—demo_si32UsbAudio Debug Table 27. Keil Unused Code Removal Comparison—CoreMark Debug Size Table 28. Keil Unused Code Removal Comparison—CoreMark Debug Speed
SiM3C1xx that require a reset to exit the lowest power mode. memory of the device. This involves copying data from flash to RAM and zero-filling any zero-initialized segments. Then, the reset code typically calls a system initialization function and jumps to main. always be compiled with the fastest speed optimization to ensure it takes as little time as possible. si32HalOption_disable_pin_reset_delay symbol in the project.
- Right-click on the project_name in the Project window and select Options for Target ‘project_name’ or
go to ProjectOptions for Target ‘project_name’.
- Use the Define text box to add or remove project symbols.
Figure 13. Adding a Project Define Symbol in the µVision IDE RESETb to the fall of a port pin at the beginning of main() on an oscilloscope. Table 29. Keil Toolchain Library Usage Comparison—sim3u1xx_Blinky Debug Reset Sequence
28 Rev. 0.1 CONTACT INFORMATION Silicon Laboratories Inc.
400 West Cesar Chavez
Austin, TX 78701 Tel: 1+(512) 416-8500 Fax: 1+(512) 416-9669 Toll Free: 1+(877) 444-3032 Please visit the Silicon Labs Technical Support web page: https://www.silabs.com/support/pages/contacttechnicalsupport.aspx and register to submit a technical support request. Patent Notice Silicon Labs invests in research and development to help our customers differentiate in the market with innovative low-power, small size, analog- intensive mixed-signal solutions. Silicon Labs' extensive patent portfolio is a testament to our unique approach and world-class engineering team. Silicon Laboratories and Silicon Labs are trademarks of Silicon Laboratories Inc. Other products or brandnames mentioned herein are trademarks or registered trademarks of their respective holders. The information in this document is believed to be accurate in all respects at the time of publication but is subject to change without notice. Silicon Laboratories assumes no responsibility for errors and omissions, and disclaims responsibility for any consequences resulting from the use of information included herein. Additionally, Silicon Laboratories assumes no responsibility for the functioning of undescribed features or parameters. Silicon Laboratories reserves the right to make changes without further notice. Silicon Laboratories makes no warranty, rep- resentation or guarantee regarding the suitability of its products for any particular purpose, nor does Silicon Laboratories assume any liability arising out of the application or use of any product or circuit, and specifically disclaims any and all liability, including without limitation conse- quential or incidental damages. Silicon Laboratories products are not designed, intended, or authorized for use in applications intended to support or sustain life, or for any other application in which the failure of the Silicon Laboratories product could create a situation where per- sonal injury or death may occur. Should Buyer purchase or use Silicon Laboratories products for any such unintended or unauthorized ap- plication, Buyer shall indemnify and hold Silicon Laboratories harmless against all claims and damages.