Lab: Parallel Profiler

Assigned
  • February 20, 2019
Due
  • April 1, 2019 by 10:30pm
Collaboration
You may work individually or in pairs on this lab. If you choose to work with a partner you may choose your own group. At the end of class on our first day with this lab I will collect a list of groups for this lab. You may not change your decision to work individually or your with your group after our first lab day.
Submitting
Send your code in a single profiler.tar.gz attachment, which should contain a directory with all of the code and any other files required to build your profiler.

For this lab, you will implement a basic sampling profiler for parallel programs. Your profiler won’t use any of the tricks we’ve seen in research papers on parallel profiling; instead, it will use sampling to estimate the time that each thread spends executing each function. This is a conventional approach to profiling that originated with single-threaded programs, but a few widely-used profilers implement this technique for parallel programs as well. If you are interested in implementing a more sophisticated technique (either from a paper or something of your own creation) then you should consider that as a final project extension to this lab.

To get started, download the starter code archive profiler.tar.gz and extract it. The starter code includes a Makefile and a single source file that implements a very basic profiling tool. All this tool does is use the Linux perf_event_open system call to set up a hardware performance counter, run a program in a child process, and report the count of hardware events. The starter code should serve as a good starting point for your implementation, which will require that you use perf_event_open’s sampling features. We’ll spend some time discussing this implementation in class.

Running the Profiler

The starter code already implements this command line interface; just make sure to preserve it as you add to the profiler. To profile a program, run the profiler executable, followed by the command you would like to profile and any of its command line arguments. Here is an example execution of the ls command with our basic profiler:

$ ./profiler ls
Makefile  profiler  profiler.c

Profiler Output:
ref cycles: 1719250

As you can see, the ls program produces its output, followed by a count of hardware events from the profiler. We’ll talk about what your completed profiler should produce as output in the next section.

Required Profiler Output

Instead of reporting a basic count, your profiler should give statistics on each thread. For example, here is the output for a hypothetical two-thread program.

$ ./profiler test1

Profiler Output:
  thread 0
    75% do_work
    20% main
    3%  pthread_create
  
  thread 1
    85% do_work
    15% thread_fn

As you can see, the profiler reports a percentage for each function run in each thread. Once you have your profiler set up to collect samples, you can compute this percentage by counting what share of samples in a given thread fall within each function.

We’ll spend some time in class discussing a technique for converting sample addresses to function names.