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_SETUP globally at the top of your file
  • provf_START at the beginning of main()
  • provf_FINISH just before returning from main()
  • provf_CALL as the first line of a function body
  • provf_RETURN just 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.

Built With

Share this project: