If you want to profile your RISC-V program in-hardware, you basically have one option: spend $1000 on a SoC that can run Linux and hope the RISC-V port of
gprof is reliable. I wanted a profiling framework that would work on embedded systems and deliver results that were at least kinda accurate.
What it does
Using proVfesr is simple -- just
#include "provfesr.h" in your C codebase.
Then, place the following macros:
provf_SETUPglobally at the top of your file
provf_STARTat the beginning of main()
provf_FINISHjust before returning from main()
provf_CALLas the first line of a function body
provf_RETURNjust before you return from a function body
After that, just compile and read the colorful output over your UART!
How I built it
proVfesr is written in C99 using the SiFive Metal library, which allows for a layer of abstraction ( and portability ) over critical operations like reading the hardware realtime clock and instruction counter. These measurements are used to calculate the time and processor cycles expended on each function.
Challenges I ran into
proVfesr doesn't really work, yet. The C preprocessor is notoriously finnicky, and targeting an embedded system is much more difficult that a userspace application. I don't exactly know the clock speeds of my device, and without a floating point processor, simple concepts like "percentages" are almost impossible.
Accomplishments that I'm proud of
proVfesr uses the fact that most sane programmers write functions on different lines as a hashing feature: the LINE macro will be unique for all invocations of provf_CALL. Similarly, the func macro will expand to the function name, so meaningful output can come from macros that don't require the user to provide arguments.
What I learned
Lots of stuff. Instruction pipelines, timer interrupts... this was a pretty rewarding endevour.