• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #pragma once
2 
3 /* for measurement of CPU cycles ..
4  *
5  * requires
6  *   sudo apt-get install libpapi-dev papi-tools
7  * on debian/ubuntu linux distributions
8  *
9  */
10 
11 #ifdef HAVE_PAPI
12 #include <papi.h>
13 #endif
14 
15 #include <stdio.h>
16 
17 
18 struct papi_perf_counter
19 {
papi_perf_counterpapi_perf_counter20     papi_perf_counter()
21         : realTime(0.0F), processTime(0.0F), instructions(0LL), ipc(0.0F)
22         , started(false), finished(false), print_at_destruction(false)
23     { }
24 
25     papi_perf_counter(int _start, bool print_at_destruction_ = true)
print_at_destructionpapi_perf_counter26         : print_at_destruction(print_at_destruction_)
27     {
28         (void)_start;
29         start();
30     }
31 
~papi_perf_counterpapi_perf_counter32     ~papi_perf_counter()
33     {
34         if (print_at_destruction)
35             print(stderr);
36     }
37 
startpapi_perf_counter38     bool start()
39     {
40         static bool reported_start_error = false;
41 #ifdef HAVE_PAPI
42         int ret = PAPI_ipc(&realTime, &processTime, &instructions, &ipc);
43         if (ret && !reported_start_error)
44         {
45             reported_start_error = true;
46             fprintf(stderr, "papi_perf_counter::start(): PAPI_ipc() returned error %d\n", ret);
47         }
48 #else
49         if (!reported_start_error)
50         {
51             reported_start_error = true;
52             fprintf(stderr, "papi_perf_counter::start(): no HAVE_PAPI\n");
53         }
54         int ret = 1;
55 #endif
56         started = (!ret);
57         finished = false;
58         return started;
59     }
60 
finishpapi_perf_counter61     bool finish()
62     {
63         papi_perf_counter end(1, false);
64         if (started && !finished && end.started)
65         {
66             realTime = end.realTime - realTime;
67             processTime = end.processTime - processTime;
68             instructions = end.instructions - instructions;
69             ipc = end.ipc;
70             finished = true;
71             return true;
72         }
73         return false;
74     }
75 
76     void print(FILE *f = stdout)
77     {
78         if (started && !finished)
79             finish();
80         if (!started || !finished)
81             return;
82         double cycles = instructions / ipc;
83         fprintf(f, "real %g, process %g, instructions %lld, ins/cycle %f => cycles %g\n"
84                 , realTime, processTime, instructions, ipc, cycles
85                 );
86         started = false;
87     }
88 
89     float realTime;
90     float processTime;
91     long long instructions;
92     float ipc;
93     bool started;
94     bool finished;
95     bool print_at_destruction;
96 };
97 
98