/**************************************************************************
*
* Copyright 2012 VMware, Inc.
+ * Copyright 2013 Intel, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
**************************************************************************/
#include "trace_profiler.hpp"
+#include "os_time.hpp"
#include <iostream>
#include <string.h>
-#include <assert.h>
#include <sstream>
-#include "os_time.hpp"
namespace trace {
Profiler::Profiler()
: baseGpuTime(0),
baseCpuTime(0),
+ minCpuTime(1000),
+ baseVsizeUsage(0),
+ baseRssUsage(0),
cpuTimes(false),
gpuTimes(true),
- pixelsDrawn(false)
+ pixelsDrawn(false),
+ memoryUsage(false)
{
}
{
}
-void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_)
+void Profiler::setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_)
{
cpuTimes = cpuTimes_;
gpuTimes = gpuTimes_;
pixelsDrawn = pixelsDrawn_;
+ memoryUsage = memoryUsage_;
+
+ 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;
+}
+
+int64_t Profiler::getBaseCpuTime()
+{
+ return baseCpuTime;
+}
+
+int64_t Profiler::getBaseGpuTime()
+{
+ return baseGpuTime;
+}
- std::cout << "# frame_begin no gpu_start cpu_start" << std::endl;
- std::cout << "# frame_end no gpu_end gpu_dura cpu_end cpu_dura" << std::endl;
- std::cout << "# call no gpu_start gpu_dura cpu_start cpu_dura pixels program name" << std::endl;
+int64_t Profiler::getBaseVsizeUsage()
+{
+ return baseVsizeUsage;
+}
+
+int64_t Profiler::getBaseRssUsage()
+{
+ return baseRssUsage;
+}
+
+void Profiler::setBaseCpuTime(int64_t cpuStart)
+{
+ baseCpuTime = cpuStart;
+}
+
+void Profiler::setBaseGpuTime(int64_t gpuStart)
+{
+ baseGpuTime = gpuStart;
+}
+
+void Profiler::setBaseVsizeUsage(int64_t vsizeStart)
+{
+ baseVsizeUsage = vsizeStart;
+}
+
+void Profiler::setBaseRssUsage(int64_t rssStart)
+{
+ baseRssUsage = rssStart;
+}
+
+bool Profiler::hasBaseTimes()
+{
+ return baseCpuTime != 0 || baseGpuTime != 0;
}
void Profiler::addCall(unsigned no,
const char *name,
unsigned program,
- uint64_t pixels,
- uint64_t gpuStart, uint64_t gpuDuration,
- uint64_t cpuStart, uint64_t cpuDuration)
+ int64_t pixels,
+ int64_t gpuStart, int64_t gpuDuration,
+ int64_t cpuStart, int64_t cpuDuration,
+ int64_t vsizeStart, int64_t vsizeDuration,
+ int64_t rssStart, int64_t rssDuration)
{
- if (baseGpuTime == 0) {
- baseGpuTime = gpuStart;
- }
-
- if (baseCpuTime == 0) {
- baseCpuTime = cpuStart;
- }
-
- if (gpuTimes) {
+ if (gpuTimes && gpuStart) {
gpuStart -= baseGpuTime;
} else {
gpuStart = 0;
gpuDuration = 0;
}
- if (cpuTimes) {
- double cpuTimeScale = 1.0E9 / os::timeFrequency;
- cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
- cpuDuration = cpuDuration * cpuTimeScale;
+ if (cpuTimes && cpuStart) {
+ cpuStart = cpuStart - baseCpuTime;
+
+ if (cpuDuration < minCpuTime) {
+ return;
+ }
} else {
cpuStart = 0;
cpuDuration = 0;
pixels = 0;
}
+ if (!memoryUsage || !vsizeStart || !rssStart) {
+ vsizeStart = 0;
+ vsizeDuration = 0;
+ rssStart = 0;
+ rssDuration = 0;
+ }
+
std::cout << "call"
<< " " << no
<< " " << gpuStart
<< " " << gpuDuration
<< " " << cpuStart
<< " " << cpuDuration
+ << " " << vsizeStart
+ << " " << vsizeDuration
+ << " " << rssStart
+ << " " << rssDuration
<< " " << pixels
<< " " << program
<< " " << name
<< std::endl;
}
-void Profiler::addFrameStart(unsigned no, uint64_t gpuStart, uint64_t cpuStart)
-{
- if (baseGpuTime == 0) {
- baseGpuTime = gpuStart;
- }
-
- if (baseCpuTime == 0) {
- baseCpuTime = cpuStart;
- }
-
- lastFrame.no = no;
- lastFrame.gpuStart = gpuStart;
- lastFrame.cpuStart = cpuStart;
-
- if (gpuTimes) {
- gpuStart = gpuStart - baseGpuTime;
- } else {
- gpuStart = 0;
- }
-
- if (cpuTimes) {
- double cpuTimeScale = 1.0E9 / os::timeFrequency;
- cpuStart = (cpuStart - baseCpuTime) * cpuTimeScale;
- } else {
- cpuStart = 0;
- }
-
- std::cout << "frame_begin"
- << " " << no
- << " " << gpuStart
- << " " << cpuStart
- << std::endl;
-}
-
-void Profiler::addFrameEnd(uint64_t gpuEnd, uint64_t cpuEnd)
+void Profiler::addFrameEnd()
{
- uint64_t gpuDuration, cpuDuration;
-
- if (gpuTimes) {
- gpuDuration = gpuEnd - lastFrame.gpuStart;
- gpuEnd = gpuEnd - baseGpuTime;
- } else {
- gpuEnd = 0;
- gpuDuration = 0;
- }
-
- if (cpuTimes) {
- double cpuTimeScale = 1.0E9 / os::timeFrequency;
- cpuDuration = (cpuEnd - lastFrame.cpuStart) * cpuTimeScale;
- cpuEnd = (cpuEnd - baseCpuTime) * cpuTimeScale;
- } else {
- cpuEnd = 0;
- cpuDuration = 0;
- }
-
- std::cout << "frame_end"
- << " " << lastFrame.no
- << " " << gpuEnd
- << " " << gpuDuration
- << " " << cpuEnd
- << " " << cpuDuration
- << std::endl;
+ std::cout << "frame_end" << std::endl;
}
void Profiler::parseLine(const char* in, Profile* profile)
{
std::stringstream line(in, std::ios_base::in);
std::string type;
+ static int64_t lastGpuTime;
+ static int64_t lastCpuTime;
+ static int64_t lastVsizeUsage;
+ static int64_t lastRssUsage;
- if (in[0] == '#' || strlen(in) < 12)
+ if (in[0] == '#' || strlen(in) < 4)
return;
+ if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
+ lastGpuTime = 0;
+ lastCpuTime = 0;
+ lastVsizeUsage = 0;
+ lastRssUsage = 0;
+ }
+
line >> type;
if (type.compare("call") == 0) {
- assert(profile->frames.size());
Profile::Call call;
line >> call.no
>> call.gpuDuration
>> call.cpuStart
>> call.cpuDuration
+ >> call.vsizeStart
+ >> call.vsizeDuration
+ >> call.rssStart
+ >> call.rssDuration
>> call.pixels
>> call.program
>> call.name;
- profile->frames.back().calls.push_back(call);
- } else if (type.compare("frame_begin") == 0) {
+ if (lastGpuTime < call.gpuStart + call.gpuDuration) {
+ lastGpuTime = call.gpuStart + call.gpuDuration;
+ }
+
+ if (lastCpuTime < call.cpuStart + call.cpuDuration) {
+ lastCpuTime = call.cpuStart + call.cpuDuration;
+ }
+
+ if (lastVsizeUsage < call.vsizeStart + call.vsizeDuration) {
+ lastVsizeUsage = call.vsizeStart + call.vsizeDuration;
+ }
+
+ if (lastRssUsage < call.rssStart + call.rssDuration) {
+ lastRssUsage = call.rssStart + call.rssDuration;
+ }
+
+ profile->calls.push_back(call);
+
+ if (call.pixels >= 0) {
+ if (profile->programs.size() <= call.program) {
+ profile->programs.resize(call.program + 1);
+ }
+
+ Profile::Program& program = profile->programs[call.program];
+ program.cpuTotal += call.cpuDuration;
+ program.gpuTotal += call.gpuDuration;
+ program.pixelTotal += call.pixels;
+ program.vsizeTotal += call.vsizeDuration;
+ program.rssTotal += call.rssDuration;
+ program.calls.push_back(profile->calls.size() - 1);
+ }
+ } else if (type.compare("frame_end") == 0) {
Profile::Frame frame;
- frame.gpuDuration = 0;
- frame.cpuDuration = 0;
+ frame.no = profile->frames.size();
- line >> frame.no
- >> frame.gpuStart
- >> frame.cpuStart;
+ if (frame.no == 0) {
+ frame.gpuStart = 0;
+ frame.cpuStart = 0;
+ frame.vsizeStart = 0;
+ frame.rssStart = 0;
+ frame.calls.begin = 0;
+ } else {
+ frame.gpuStart = profile->frames.back().gpuStart + profile->frames.back().gpuDuration;
+ frame.cpuStart = profile->frames.back().cpuStart + profile->frames.back().cpuDuration;
+ frame.vsizeStart = profile->frames.back().vsizeStart + profile->frames.back().vsizeDuration;
+ frame.rssStart = profile->frames.back().rssStart + profile->frames.back().rssDuration;
+ frame.calls.begin = profile->frames.back().calls.end + 1;
+ }
+
+ frame.gpuDuration = lastGpuTime - frame.gpuStart;
+ frame.cpuDuration = lastCpuTime - frame.cpuStart;
+ frame.vsizeDuration = lastVsizeUsage - frame.vsizeStart;
+ frame.rssDuration = lastRssUsage - frame.rssStart;
+ frame.calls.end = profile->calls.size() - 1;
profile->frames.push_back(frame);
- } else if (type.compare("frame_end") == 0) {
- assert(profile->frames.size());
- Profile::Frame& frame = profile->frames.back();
- int64_t skipi64;
-
- line >> frame.no
- >> skipi64
- >> frame.gpuDuration
- >> skipi64
- >> frame.cpuDuration;
}
}
}