1 /**************************************************************************
3 * Copyright 2012 VMware, Inc.
4 * Copyright 2013 Intel, Inc.
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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
25 **************************************************************************/
27 #include "trace_profiler.hpp"
28 #include "os_time.hpp"
51 void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_)
55 pixelsDrawn = pixelsDrawn_;
56 memoryUsage = memoryUsage_;
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;
61 int64_t Profiler::getBaseCpuTime()
66 int64_t Profiler::getBaseGpuTime()
71 int64_t Profiler::getBaseVsizeUsage()
73 return baseVsizeUsage;
76 int64_t Profiler::getBaseRssUsage()
81 void Profiler::setBaseCpuTime(int64_t cpuStart)
83 baseCpuTime = cpuStart;
86 void Profiler::setBaseGpuTime(int64_t gpuStart)
88 baseGpuTime = gpuStart;
91 void Profiler::setBaseVsizeUsage(int64_t vsizeStart)
93 baseVsizeUsage = vsizeStart;
96 void Profiler::setBaseRssUsage(int64_t rssStart)
98 baseRssUsage = rssStart;
101 bool Profiler::hasBaseTimes()
103 return baseCpuTime != 0 || baseGpuTime != 0;
106 void Profiler::addCall(unsigned no,
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)
115 if (gpuTimes && gpuStart) {
116 gpuStart -= baseGpuTime;
122 if (cpuTimes && cpuStart) {
123 cpuStart = cpuStart - baseCpuTime;
125 if (cpuDuration < minCpuTime) {
137 if (!memoryUsage || !vsizeStart || !rssStart) {
147 << " " << gpuDuration
149 << " " << cpuDuration
151 << " " << vsizeDuration
153 << " " << rssDuration
160 void Profiler::addFrameEnd()
162 std::cout << "frame_end" << std::endl;
165 void Profiler::parseLine(const char* in, Profile* profile)
167 std::stringstream line(in, std::ios_base::in);
169 static int64_t lastGpuTime;
170 static int64_t lastCpuTime;
171 static int64_t lastVsizeUsage;
172 static int64_t lastRssUsage;
174 if (in[0] == '#' || strlen(in) < 4)
177 if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
186 if (type.compare("call") == 0) {
195 >> call.vsizeDuration
202 if (lastGpuTime < call.gpuStart + call.gpuDuration) {
203 lastGpuTime = call.gpuStart + call.gpuDuration;
206 if (lastCpuTime < call.cpuStart + call.cpuDuration) {
207 lastCpuTime = call.cpuStart + call.cpuDuration;
210 if (lastVsizeUsage < call.vsizeStart + call.vsizeDuration) {
211 lastVsizeUsage = call.vsizeStart + call.vsizeDuration;
214 if (lastRssUsage < call.rssStart + call.rssDuration) {
215 lastRssUsage = call.rssStart + call.rssDuration;
218 profile->calls.push_back(call);
220 if (call.pixels >= 0) {
221 if (profile->programs.size() <= call.program) {
222 profile->programs.resize(call.program + 1);
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);
233 } else if (type.compare("frame_end") == 0) {
234 Profile::Frame frame;
235 frame.no = profile->frames.size();
240 frame.vsizeStart = 0;
242 frame.calls.begin = 0;
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;
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;
257 profile->frames.push_back(frame);