]> git.cworth.org Git - apitrace/blob - common/trace_profiler.cpp
Use skiplist-based FastCallSet within trace::CallSet
[apitrace] / common / trace_profiler.cpp
1 /**************************************************************************
2  *
3  * Copyright 2012 VMware, Inc.
4  * Copyright 2013 Intel, Inc.
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 #include "trace_profiler.hpp"
28 #include "os_time.hpp"
29 #include <iostream>
30 #include <string.h>
31 #include <sstream>
32
33 namespace trace {
34 Profiler::Profiler()
35     : baseGpuTime(0),
36       baseCpuTime(0),
37       minCpuTime(1000),
38       baseVsizeUsage(0),
39       baseRssUsage(0),
40       cpuTimes(false),
41       gpuTimes(true),
42       pixelsDrawn(false),
43       memoryUsage(false)
44 {
45 }
46
47 Profiler::~Profiler()
48 {
49 }
50
51 void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_)
52 {
53     cpuTimes = cpuTimes_;
54     gpuTimes = gpuTimes_;
55     pixelsDrawn = pixelsDrawn_;
56     memoryUsage = memoryUsage_;
57
58     std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura vsize_start vsize_dura rss_start rss_dura pixels program name" << std::endl;
59 }
60
61 int64_t Profiler::getBaseCpuTime()
62 {
63     return baseCpuTime;
64 }
65
66 int64_t Profiler::getBaseGpuTime()
67 {
68     return baseGpuTime;
69 }
70
71 int64_t Profiler::getBaseVsizeUsage()
72 {
73     return baseVsizeUsage;
74 }
75
76 int64_t Profiler::getBaseRssUsage()
77 {
78     return baseRssUsage;
79 }
80
81 void Profiler::setBaseCpuTime(int64_t cpuStart)
82 {
83     baseCpuTime = cpuStart;
84 }
85
86 void Profiler::setBaseGpuTime(int64_t gpuStart)
87 {
88     baseGpuTime = gpuStart;
89 }
90
91 void Profiler::setBaseVsizeUsage(int64_t vsizeStart)
92 {
93     baseVsizeUsage = vsizeStart;
94 }
95
96 void Profiler::setBaseRssUsage(int64_t rssStart)
97 {
98     baseRssUsage = rssStart;
99 }
100
101 bool Profiler::hasBaseTimes()
102 {
103     return baseCpuTime != 0 || baseGpuTime != 0;
104 }
105
106 void Profiler::addCall(unsigned no,
107                        const char *name,
108                        unsigned program,
109                        int64_t pixels,
110                        int64_t gpuStart, int64_t gpuDuration,
111                        int64_t cpuStart, int64_t cpuDuration,
112                        int64_t vsizeStart, int64_t vsizeDuration,
113                        int64_t rssStart, int64_t rssDuration)
114 {
115     if (gpuTimes && gpuStart) {
116         gpuStart -= baseGpuTime;
117     } else {
118         gpuStart = 0;
119         gpuDuration = 0;
120     }
121
122     if (cpuTimes && cpuStart) {
123         cpuStart = cpuStart - baseCpuTime;
124
125         if (cpuDuration < minCpuTime) {
126             return;
127         }
128     } else {
129         cpuStart = 0;
130         cpuDuration = 0;
131     }
132
133     if (!pixelsDrawn) {
134         pixels = 0;
135     }
136
137     if (!memoryUsage || !vsizeStart || !rssStart) {
138         vsizeStart = 0;
139         vsizeDuration = 0;
140         rssStart = 0;
141         rssDuration = 0;
142     }
143
144     std::cout << "call"
145               << " " << no
146               << " " << gpuStart
147               << " " << gpuDuration
148               << " " << cpuStart
149               << " " << cpuDuration
150               << " " << vsizeStart
151               << " " << vsizeDuration
152               << " " << rssStart
153               << " " << rssDuration
154               << " " << pixels
155               << " " << program
156               << " " << name
157               << std::endl;
158 }
159
160 void Profiler::addFrameEnd()
161 {
162     std::cout << "frame_end" << std::endl;
163 }
164
165 void Profiler::parseLine(const char* in, Profile* profile)
166 {
167     std::stringstream line(in, std::ios_base::in);
168     std::string type;
169     static int64_t lastGpuTime;
170     static int64_t lastCpuTime;
171     static int64_t lastVsizeUsage;
172     static int64_t lastRssUsage;
173
174     if (in[0] == '#' || strlen(in) < 4)
175         return;
176
177     if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
178         lastGpuTime = 0;
179         lastCpuTime = 0;
180         lastVsizeUsage = 0;
181         lastRssUsage = 0;
182     }
183
184     line >> type;
185
186     if (type.compare("call") == 0) {
187         Profile::Call call;
188
189         line >> call.no
190              >> call.gpuStart
191              >> call.gpuDuration
192              >> call.cpuStart
193              >> call.cpuDuration
194              >> call.vsizeStart
195              >> call.vsizeDuration
196              >> call.rssStart
197              >> call.rssDuration
198              >> call.pixels
199              >> call.program
200              >> call.name;
201
202         if (lastGpuTime < call.gpuStart + call.gpuDuration) {
203             lastGpuTime = call.gpuStart + call.gpuDuration;
204         }
205
206         if (lastCpuTime < call.cpuStart + call.cpuDuration) {
207             lastCpuTime = call.cpuStart + call.cpuDuration;
208         }
209
210         if (lastVsizeUsage < call.vsizeStart + call.vsizeDuration) {
211             lastVsizeUsage = call.vsizeStart + call.vsizeDuration;
212         }
213
214         if (lastRssUsage < call.rssStart + call.rssDuration) {
215             lastRssUsage = call.rssStart + call.rssDuration;
216         }
217
218         profile->calls.push_back(call);
219
220         if (call.pixels >= 0) {
221             if (profile->programs.size() <= call.program) {
222                 profile->programs.resize(call.program + 1);
223             }
224
225             Profile::Program& program = profile->programs[call.program];
226             program.cpuTotal += call.cpuDuration;
227             program.gpuTotal += call.gpuDuration;
228             program.pixelTotal += call.pixels;
229             program.vsizeTotal += call.vsizeDuration;
230             program.rssTotal += call.rssDuration;
231             program.calls.push_back(profile->calls.size() - 1);
232         }
233     } else if (type.compare("frame_end") == 0) {
234         Profile::Frame frame;
235         frame.no = profile->frames.size();
236
237         if (frame.no == 0) {
238             frame.gpuStart = 0;
239             frame.cpuStart = 0;
240             frame.vsizeStart = 0;
241             frame.rssStart = 0;
242             frame.calls.begin = 0;
243         } else {
244             frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
245             frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
246             frame.vsizeStart = profile->frames.back().vsizeStart + profile->frames.back().vsizeDuration;
247             frame.rssStart = profile->frames.back().rssStart + profile->frames.back().rssDuration;
248             frame.calls.begin = profile->frames.back().calls.end + 1;
249         }
250
251         frame.gpuDuration = lastGpuTime - frame.gpuStart;
252         frame.cpuDuration = lastCpuTime - frame.cpuStart;
253         frame.vsizeDuration = lastVsizeUsage - frame.vsizeStart;
254         frame.rssDuration = lastRssUsage - frame.rssStart;
255         frame.calls.end = profile->calls.size() - 1;
256
257         profile->frames.push_back(frame);
258     }
259 }
260 }