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 double cpuTimeScale = 1.0E9 / os::timeFrequency;
124 cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
125 cpuDuration = cpuDuration * cpuTimeScale;
127 if (cpuDuration < minCpuTime) {
139 if (!memoryUsage || !vsizeStart || !rssStart) {
149 << " " << gpuDuration
151 << " " << cpuDuration
153 << " " << vsizeDuration
155 << " " << rssDuration
162 void Profiler::addFrameEnd()
164 std::cout << "frame_end" << std::endl;
167 void Profiler::parseLine(const char* in, Profile* profile)
169 std::stringstream line(in, std::ios_base::in);
171 static int64_t lastGpuTime;
172 static int64_t lastCpuTime;
173 static int64_t lastVsizeUsage;
174 static int64_t lastRssUsage;
176 if (in[0] == '#' || strlen(in) < 4)
179 if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
188 if (type.compare("call") == 0) {
197 >> call.vsizeDuration
204 if (lastGpuTime < call.gpuStart + call.gpuDuration) {
205 lastGpuTime = call.gpuStart + call.gpuDuration;
208 if (lastCpuTime < call.cpuStart + call.cpuDuration) {
209 lastCpuTime = call.cpuStart + call.cpuDuration;
212 if (lastVsizeUsage < call.vsizeStart + call.vsizeDuration) {
213 lastVsizeUsage = call.vsizeStart + call.vsizeDuration;
216 if (lastRssUsage < call.rssStart + call.rssDuration) {
217 lastRssUsage = call.rssStart + call.rssDuration;
220 profile->calls.push_back(call);
222 if (call.pixels >= 0) {
223 if (profile->programs.size() <= call.program) {
224 profile->programs.resize(call.program + 1);
227 Profile::Program& program = profile->programs[call.program];
228 program.cpuTotal += call.cpuDuration;
229 program.gpuTotal += call.gpuDuration;
230 program.pixelTotal += call.pixels;
231 program.vsizeTotal += call.vsizeDuration;
232 program.rssTotal += call.rssDuration;
233 program.calls.push_back(profile->calls.size() - 1);
235 } else if (type.compare("frame_end") == 0) {
236 Profile::Frame frame;
237 frame.no = profile->frames.size();
242 frame.vsizeStart = 0;
244 frame.calls.begin = 0;
246 frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
247 frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
248 frame.vsizeStart = profile->frames.back().vsizeStart + profile->frames.back().vsizeDuration;
249 frame.rssStart = profile->frames.back().rssStart + profile->frames.back().rssDuration;
250 frame.calls.begin = profile->frames.back().calls.end + 1;
253 frame.gpuDuration = lastGpuTime - frame.gpuStart;
254 frame.cpuDuration = lastCpuTime - frame.cpuStart;
255 frame.vsizeDuration = lastVsizeUsage - frame.vsizeStart;
256 frame.rssDuration = lastRssUsage - frame.rssStart;
257 frame.calls.end = profile->calls.size() - 1;
259 profile->frames.push_back(frame);