Tutorial - Using Profiling Information to Improve Locate Options

Frozen Content

Parent article: Profiling

Profiling is the process of collecting statistical data about a running application. With these data you can analyze which functions are called, how often they are called and what their execution time is. This tutorial describes the process of using profiling information to locate the most time-consuming functions in internal (fastest) memory by setting the project Locate Options.

This tutorial uses the Graphics.PrjFpg example FPGA design project, targeted to a daughter board device on a NanoBoard NB2. This project is not installed by default as part of your Altium Designer installation. It can be sourced from the Reference Designs page of the AltiumLive community site. From this page, navigate to Soft-Designs/Display/Graphics. For this tutorial, we will assume that the project has been procured and resides in the \Examples\Soft Designs\Display\Graphics folder of the Altium Designer installation.

If you are using a 3000-series NanoBoard, you can use the NB3000_Graphics.PrjFpg example FPGA design project, which has been modified to suit this series of NanoBoards. This can be sourced by navigating to Soft-Designs/Display/NB3000 Graphics on the Reference Designs page of the AltiumLive site.

Open the Project

Let's go ahead and open the example project:

  1. Choose the Open Project command from the main File menu – the Choose Project to Open dialog will appear.
     
  2. Navigate to the file Examples\Soft Designs\Display\Graphics\Graphics.PrjFpg and click Open.
     

     
  3. The Graphics project is added to the current workspace and listed in the Projects panel.
     

Check the Embedded Project Profiling Options

Now we need to access the embedded software project and ensure the options to generate profiling information are set up correctly.

  1. In the Projects panel, right-click on the Graphics.PrjEmb entry and choose the Project Options command from the context menu that appears. Alternatively, use the Project»Project Options command from the main menus. The Options for Embedded Project dialog appears.
     
  2. In the Compiler Options tab, select C Compiler»Debug Information. In the options list on the right, ensure that the Generate profiling information option is enabled in the General options. Under Custom Profiling ensure that the Call graph and Function timers options are both enabled.
     

     
  3. Click OK to confirm the settings and exit the dialog. Save the changes (File»Save All).

Target the Design to the FPGA Device

We need to specify which physical FPGA device we want to use – the target for our design and the end medium into which the design will ultimately be programmed and run. For this tutorial, we will target an FPGA device located on a 3-connector daughter board that is plugged into a NanoBoard NB2.

  1. Access the Devices view (View»Devices View) and ensure that the Live option at the top-right of the view is enabled.
     
  2. The Graphics project comes with a range of predefined configurations and assigned constraint files, based on rev.8 of the NanoBoard NB2 and a variety of different plugin daughter boards. The correct Project-Configuration pairing should appear in the field below the physical device icon in the Devices view – chosen for the hardware configuration you have.
     

Process the Design

Now that the design is targeted to our daughter board FPGA device, we can go ahead and process the design – ultimately creating the required FPGA programming file with which to program the target device.

  1. In the associated 'Process Flow' for the physical device, click on the Program FPGA button – the last stage in the flow. The design will be compiled, synthesized and the vendor tools invoked. Ultimately the FPGA programming file will be generated and downloaded, via JTAG, to the physical device on the daughter board.
     

     
  2. Once the design has been downloaded, the text underneath the physical device's icon in the Devices view will change from Reset to Programmed. On the hardware side, the 'Program' LED on the daughter board will be lit (Green), confirming the design has been loaded into the physical device.

Execute the Embedded Software Application

To get profiling information the embedded software application should be executed in the debugger. At application end the collected statistical data is then transferred from the device to the host.

The Graphics application ends after drawing some graphics, but many embedded programs will run forever. Those applications should be rewritten first to call exit() at a specific moment.

Let's go ahead and start a debug session:

  1. With the design programmed into the target FPGA device, the Soft Devices region of the Devices view now presents an icon for the TSK3000A processor. Right-click on this icon and choose the Debug command from the context menu that appears. The embedded project for the software running in the processor will initially be recompiled and the debug session will commence. The relevant source code document (in this case main.c) will be opened and the current execution point will be set to the first line of executable code.
     

     
  2. Commence execution of the software using the Debug»Run command (shortcut: F9), or by clicking the button on the Debug toolbar.
     

     
  3. The application is executed. At the end of execution, all gathered data is passed to the debugger. When ready, the profiling results are displayed in the Profiler view.
     

Analyze the Profiling Results

The Profiler view shows a lot of information. For now we are interested in the following fields:

  • Function – the function for which profiling data is gathered.
  • Module – the C source document in which the function resides.
  • Total Time – the total amount of time that was spent in this function and all of its sub-functions.
  • Self Time – the amount of time that was spent in the function itself. This excludes the time spent in the sub-functions.

Normally the total execution time of an example is almost equal to the Total Time of the main function. In our case this is 0.05878 seconds (nearly 100%). To find good function candidates to force into internal memory we are mostly interested in Self Time values.

Click on the Self Time column header to sort the data by Self Time.

We now have the most time consuming functions at the top. Normally it is worth to take a closer look at those functions to find ways for improvement. For this tutorial we will skip that part and only focus on the kind of memory. We want to force the Linker to put the top four time consuming functions into internal (fastest) memory.

Your order of functions may differ from this tutorial. This is because the locator is free to choose which function (or data) is put into internal memory. Different choices may result in a different order.

Set Locate Options

To modify the locate options:

  1. Access the Options for Embedded Project dialog – in the Projects panel, right-click on the Graphics.PrjEmb entry and choose the Project Options command from the context menu that appears.
     
  2. Click on the Locate Options tab. The tab presents a tree with all parts of the application. On the right-hand side there is a Memories column containing the two currently available memories MCU (internal) and SRAM (external).
     

The columns for these two memories contain status icons for all application parts. The following states are supported:

– memory is allowed for all child entries.

– memory is allowed for some (but not all) child entries. Expand the entry to show more details.

– memory is not allowed for all child entries.

For now, we will only focus on Code. Expanding the Code entry will show all application modules. Expanding a module entry will show all module functions.

Now we can start forcing some modules or functions to internal memory (MCU). This can be done by excluding those modules or functions from all external memories, in this case SRAM. Exclude the four most time consuming functions from SRAM. From the profiling results in this tutorial (may differ for your own case), these functions are:

  • _graphics_draw_horizontal_rgb565 (in the module canvas)
  • _graphics_draw_glyph (in the module graphics_draw_text)
  • _graphics_fill_segment (in the module graphics_fill_segment)
  • _get_x (in the module graphics_fill_segment).

Click OK to commit the changes and exit the dialog. Save the project (File»Save All).

Execute the Modified Embedded Software Application

  1. In the Projects panel, right-click on the Graphics.PrjEmb entry and choose the Debug MCU command from the context menu that appears. The embedded project will be relinked and the application is downloaded to the target FPGA device on the NanoBoard. A debug session will recommence – main.c will be made the active document and the current execution point will, once again, be set to the first line of executable code.
     
  2. Commence execution of the software using the Debug»Run command (shortcut: F9), or by clicking the button on the Debug toolbar.

The application is executed. At the end, new profiling information is passed to the debugger. The new profiling results will be subsequently displayed in the Profiler view.

The most obvious difference is the Total Time of function main which is reduced from 0.05878 to 0.04142 seconds. A speed improvement of almost 30%.

Compare the old Self Time and new Self Time of all the functions you put in internal memory. You can play with the Locate Options to even get better results!

You are reporting an issue with the following selected text and/or image within the active document: