Next: , Previous: Running UPC Programs, Up: Analyzing UPC Programs


3.3 Recording Phase Data in UPC

While the --inst-local and --inst-functions instrumentation options provided by ppwupcc do provide several different options for attributing performance information to specific regions of code in your program, sometimes simply having function-level performance information does not give you enough information to analyze your program. Rather, it might be useful to track time spent in a particular phase of your program's execution.

In the future, PPW may add support to automatically detect program phases based on an online analysis of barriers. In the meantime, if you'd like to collect performance information for particular phases of your program's execution, you'll need to manually add calls to PPW's measurement API in your program.

As an example, suppose you've written a UPC program that resembles the following structure:

     #include <upc.h>
     
     int main() {
       /* initialization phase */
       /* ... */
       upc_barrier;
     
       /* computation phase with N iterations */
       for (i = 0; i < N; i++) {
         /* ... */
         upc_barrier;
       }
     
       /* communication phase */
       /* ... */
       upc_barrier;
     
       return 0;
     }

and you compile this program with ppwupcc --inst-functions main.upc. When viewing this performance data, you will get information about how long each thread spent executing ‘main’, but not much information about each of the phases within your program. If your computation phase has a load-balancing problem, this might be hard to detect just by examining performance data for ‘main’. Similarly, if you have a complicated program structure where program phases are not neatly divided into function calls, then you will have a hard time localizing performance problems to particular phases of your program's execution.

Using PPW's measurement API, you would do this:

     #include <upc.h>
     #include <pupc.h>
     
     int main() {
       unsigned int evin, evcp, evcm;
     
       evin = pupc_create_event("Init phase", NULL);
       evcp = pupc_create_event("Compute phase", "%d");
       evcm = pupc_create_event("Comm phase", NULL);
     
       /* initialization phase */
       pupc_event_start(evin);
       /* ... */
       upc_barrier;
       pupc_event_end(evin);
     
       pupc_event_start(evcp, -1);
       /* computation phase with N iterations */
       for (i = 0; i < N; i++) {
         pupc_event_atomic(evcp, i);
         /* ... */
         upc_barrier;
       }
       pupc_event_end(evcp, -1);
     
       /* communication phase */
       pupc_event_start(evcm);
       /* ... */
       upc_barrier;
       pupc_event_end(evcm);
     
       return 0;
     }

For full details on the UPC measurement API, see UPC Measurement API.