|
| 1 | +Profiling Applications with GPROF |
| 2 | +================================= |
| 3 | + |
| 4 | +Applications running on the Pico can be profiled using GNU GPROF to show where the CPU is using its time |
| 5 | +on the device and how often certain functions are called. It does this by recompiling the application |
| 6 | +and adding a small preamble to each function built to identify what functions call what others (and |
| 7 | +how frequently). It also uses the ``SYSTICK`` exception timer to sample and record the PC 10,000 times |
| 8 | +per second. When an application is complete, the recorded date can be dumped to the host PC as a |
| 9 | +``gmon.,out`` file which can be processed by ``arm-none-eabi-gprof`` into useful date. |
| 10 | + |
| 11 | +s histogram of PCs and tally of function caller/callees can take a significant amount of RAM, from 100KB |
| 12 | +to 10000KB depending on the size of the application. As such, while the RP2040 **may** be able to |
| 13 | +profile small applications, this is only really recommended on the RP2350 with external PSRAM. The |
| 14 | +profiler will automatically use PSRAM when available. |
| 15 | + |
| 16 | +Profiling also adds procesing overhead in terms of the periodic sampling and the function preambles. |
| 17 | +In most cases there is no reason to enable (and many reasons to disable) profiling when an application |
| 18 | +is deployed to the field. |
| 19 | + |
| 20 | +To transfer the ``GMON.OUT`` data from the Pico to the host HP can be done by having the application |
| 21 | +write it out to an SD card or a LittleFS filesystem which is then manually dumped, but for ease of use |
| 22 | +semihosting can be used to allow the Pico (under the control of OpenOCD and GDB) to write the |
| 23 | +``gmon.out`` file directly on the host PC, ready for use. |
| 24 | + |
| 25 | +**NOTE** Semihosting only works when connected to an OpenOCD + GDB debug session. Running an application |
| 26 | +compiled for Semihosting without the debugger will cause a panic and hang the chip. |
| 27 | + |
| 28 | +As of now, only ARM has support for Semihosting or GPROF. |
| 29 | + |
| 30 | + |
| 31 | +Enabling Profiling in an Application |
| 32 | +------------------------------------ |
| 33 | + |
| 34 | +The ``Tools->Profiling->Enabled`` menu needs to be selected to enable profiling support in GCC. This will |
| 35 | +add the necessary preamble to every function compiled (**Note** that the ``libpico`` and ``libc`` will not |
| 36 | +be instrumented because they are pre-built so calls from them will not be fully instrumented. However, |
| 37 | +PC data will still be grabbed and decoded from them at runtime.) |
| 38 | + |
| 39 | +The application will automatically start collecting profiling data even before ``setup`` starts in this |
| 40 | +mode. It will continue collecting data until you stop and write out the profiling data using |
| 41 | +``rp2040.writeProfiling()`` to dump to the host, a file, serial port, etc. |
| 42 | + |
| 43 | +For example, an application which does all its processing in ``setup()`` might look like: |
| 44 | + |
| 45 | +.. code:: cpp |
| 46 | +
|
| 47 | + #include <SemiFS.h> |
| 48 | + void setup() { |
| 49 | + SerialSemi.printf("BEGIN\n"); |
| 50 | + do_some_work_that_takes_a_long_time_with_many_function_calls(); |
| 51 | + // Do lots of other work... |
| 52 | + // Now all done... |
| 53 | + SerialSemi.printf("Writing GMON.OUT\n"); |
| 54 | + SemiFS.begin(); |
| 55 | + File gmon = SemiFS.open("gmon.out", "w"); |
| 56 | + rp2040.writeProfiling(&gmon); |
| 57 | + gmon.close(); |
| 58 | + SerialSemi.printf("END\n"); |
| 59 | + } |
| 60 | + void loop() {} |
| 61 | +
|
| 62 | +
|
| 63 | +Collecting and Analyzing Profile Data |
| 64 | +------------------------------------- |
| 65 | + |
| 66 | +Running this application under `semihosting <semihosting>`_ GDB and OpenOCD generates a ``gmon.out`` file |
| 67 | +in the OpenOCD current working directory. This file, combined with the ``ELF`` binary build in the |
| 68 | +IDE and loaded through GDB, can produce profiler output using |
| 69 | + |
| 70 | +.. code:: |
| 71 | +
|
| 72 | + $ /path/to/arm-none-eabi/bin/arm-none-eabi-gprof /path/to/sketch.ino.elf /path/to/gmon.out |
| 73 | +
|
| 74 | +See the ``rp2040/Profiling.ino`` example for more details. |
0 commit comments