]> git.cworth.org Git - apitrace/blob - gui/profiling.h
Use skiplist-based FastCallSet within trace::CallSet
[apitrace] / gui / profiling.h
1 #ifndef PROFILING_H
2 #define PROFILING_H
3
4 #include <QString>
5 #include <QLocale>
6 #include "trace_profiler.hpp"
7
8 class Profiling {
9 public:
10     /**
11      * Select and show the call in main window.
12      */
13     static void jumpToCall(int index);
14
15     /**
16      * Convert a CPU / GPU time to a textual representation.
17      * This includes automatic unit selection.
18      */
19     static QString getTimeString(int64_t time, int64_t unitTime = 0)
20     {
21         QString text;
22         QString unit = " ns";
23         double unitScale = 1;
24
25         if (unitTime == 0) {
26             unitTime = time;
27         }
28
29         if (unitTime >= 60e9) {
30             int64_t mins = time / 60e9;
31             text += QString("%1 m ").arg(mins);
32
33             time -= mins * 60e9;
34             unit = " s";
35             unitScale = 1e9;
36         } else if (unitTime >= 1e9) {
37             unit = " s";
38             unitScale = 1e9;
39         } else if (unitTime >= 1e6) {
40             unit = " ms";
41             unitScale = 1e6;
42         } else if (unitTime >= 1e3) {
43             unit = QString::fromUtf8(" µs");
44             unitScale = 1e3;
45         }
46
47         /* 3 decimal places */
48         text += QString("%1").arg(time / unitScale, 0, 'f', 3);
49
50         /* Remove trailing 0 */
51         while(text.endsWith('0'))
52             text.truncate(text.length() - 1);
53
54         /* Remove trailing decimal point */
55         if (text.endsWith(QLocale::system().decimalPoint()))
56             text.truncate(text.length() - 1);
57
58         return text + unit;
59     }
60
61     template<typename val_ty, int64_t val_ty::* mem_ptr_start, int64_t val_ty::* mem_ptr_dura>
62     static typename std::vector<val_ty>::const_iterator binarySearchTimespan(
63             typename std::vector<val_ty>::const_iterator begin,
64             typename std::vector<val_ty>::const_iterator end,
65             int64_t time,
66             bool nearest = false)
67     {
68         int lower = 0;
69         int upper = end - begin;
70         int pos = (lower + upper) / 2;
71         typename std::vector<val_ty>::const_iterator itr = begin + pos;
72
73         while (!((*itr).*mem_ptr_start <= time && (*itr).*mem_ptr_start + (*itr).*mem_ptr_dura > time) && (lower <= upper)) {
74             if ((*itr).*mem_ptr_start > time) {
75                 upper = pos - 1;
76             } else {
77                 lower = pos + 1;
78             }
79
80             pos = (lower + upper) / 2;
81             itr = begin + pos;
82         }
83
84         if (nearest || lower <= upper) {
85             return itr;
86         } else {
87             return end;
88         }
89     }
90
91     static std::vector<unsigned>::const_iterator binarySearchTimespanIndexed(
92             const std::vector<trace::Profile::Call>& calls,
93             std::vector<unsigned>::const_iterator begin,
94             std::vector<unsigned>::const_iterator end,
95             int64_t time,
96             bool nearest = false)
97     {
98         int lower = 0;
99         int upper = end - begin - 1;
100         int pos = (lower + upper) / 2;
101         std::vector<unsigned>::const_iterator itr = begin + pos;
102
103         while (lower <= upper) {
104             const trace::Profile::Call& call = calls[*itr];
105
106             if (call.gpuStart <= time && call.gpuStart + call.gpuDuration > time) {
107                 break;
108             }
109
110             if (call.gpuStart > time) {
111                 upper = pos - 1;
112             } else {
113                 lower = pos + 1;
114             }
115
116             pos = (lower + upper) / 2;
117             itr = begin + pos;
118         }
119
120         if (nearest || lower <= upper) {
121             return itr;
122         } else {
123             return end;
124         }
125     }
126 };
127
128 #endif