[PATCH] Extend prifiling tool to support Vsize and Rss memory usage profile per call
Shuang He
shuang.he at intel.com
Sun Feb 17 17:36:26 PST 2013
Add one new option -pmem for retrace tool to track Visze and Rss usage during every call
Signed-off-by: Shuang He <shuang.he at intel.com>
---
CMakeLists.txt | 4 +++
common/os_memory.hpp | 66 +++++++++++++++++++++++++++++++++++++++++
common/trace_profiler.cpp | 70 +++++++++++++++++++++++++++++++++++++++++---
common/trace_profiler.hpp | 26 ++++++++++++++--
retrace/CMakeLists.txt | 6 ++++
retrace/glretrace_main.cpp | 45 ++++++++++++++++++++++++++--
retrace/retrace.hpp | 2 ++
retrace/retrace_main.cpp | 14 ++++++++-
8 files changed, 224 insertions(+), 9 deletions(-)
create mode 100644 common/os_memory.hpp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 91f1b87..90bfc87 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -191,6 +191,10 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE
)
+ CHECK_INCLUDE_FILES(proc/readproc.h READPROC_H_FOUND)
+ if (READPROC_H_FOUND)
+ add_definitions (-DHAVE_READPROC_H)
+ endif ()
endif()
if (WIN32 OR APPLE)
diff --git a/common/os_memory.hpp b/common/os_memory.hpp
new file mode 100644
index 0000000..dfee1be
--- /dev/null
+++ b/common/os_memory.hpp
@@ -0,0 +1,66 @@
+/**************************************************************************
+ *
+ * Copyright 2013 Shuang He <shuang.he at intel.com>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/*
+ * Simple OS time measurement abstraction.
+ */
+
+#ifndef _OS_MEMORY_HPP_
+#define _OS_MEMORY_HPP_
+
+#ifdef HAVE_READPROC_H
+#include <proc/readproc.h>
+
+namespace os {
+ inline long long
+ getVsize(void) {
+ proc_t proc;
+ look_up_our_self(&proc);
+ return proc.vsize;
+ }
+
+ inline long long
+ getRss(void) {
+ proc_t proc;
+ look_up_our_self(&proc);
+ return proc.rss;
+ }
+} /* namespace os */
+
+#else
+namespace os {
+ inline long long
+ getVsize(void) {
+ return 0;
+ }
+
+ inline long long
+ getRss(void) {
+ return 0;
+ }
+} /* namespace os */
+#endif
+
+#endif /* _OS_MEMORY_HPP_ */
diff --git a/common/trace_profiler.cpp b/common/trace_profiler.cpp
index 0f90ee2..d4d4260 100644
--- a/common/trace_profiler.cpp
+++ b/common/trace_profiler.cpp
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2012 VMware, Inc.
+ * Copyright 2013 Intel, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -34,9 +35,12 @@ Profiler::Profiler()
: baseGpuTime(0),
baseCpuTime(0),
minCpuTime(1000),
+ baseVsizeUsage(0),
+ baseRssUsage(0),
cpuTimes(false),
gpuTimes(true),
- pixelsDrawn(false)
+ pixelsDrawn(false),
+ memoryUsage(false)
{
}
@@ -44,13 +48,14 @@ Profiler::~Profiler()
{
}
-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 pixels program name" << std::endl;
+ 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()
@@ -63,6 +68,16 @@ int64_t Profiler::getBaseGpuTime()
return baseGpuTime;
}
+int64_t Profiler::getBaseVsizeUsage()
+{
+ return baseVsizeUsage;
+}
+
+int64_t Profiler::getBaseRssUsage()
+{
+ return baseRssUsage;
+}
+
void Profiler::setBaseCpuTime(int64_t cpuStart)
{
baseCpuTime = cpuStart;
@@ -73,6 +88,16 @@ 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;
@@ -83,7 +108,9 @@ void Profiler::addCall(unsigned no,
unsigned program,
int64_t pixels,
int64_t gpuStart, int64_t gpuDuration,
- int64_t cpuStart, int64_t cpuDuration)
+ int64_t cpuStart, int64_t cpuDuration,
+ int64_t vsizeStart, int64_t vsizeDuration,
+ int64_t rssStart, int64_t rssDuration)
{
if (gpuTimes && gpuStart) {
gpuStart -= baseGpuTime;
@@ -109,12 +136,23 @@ void Profiler::addCall(unsigned no,
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
@@ -132,6 +170,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
std::string type;
static int64_t lastGpuTime;
static int64_t lastCpuTime;
+ static int64_t lastVsizeUsage;
+ static int64_t lastRssUsage;
if (in[0] == '#' || strlen(in) < 4)
return;
@@ -139,6 +179,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
if (profile->programs.size() == 0 && profile->calls.size() == 0 && profile->frames.size() == 0) {
lastGpuTime = 0;
lastCpuTime = 0;
+ lastVsizeUsage = 0;
+ lastRssUsage = 0;
}
line >> type;
@@ -151,6 +193,10 @@ void Profiler::parseLine(const char* in, Profile* profile)
>> call.gpuDuration
>> call.cpuStart
>> call.cpuDuration
+ >> call.vsizeStart
+ >> call.vsizeDuration
+ >> call.rssStart
+ >> call.rssDuration
>> call.pixels
>> call.program
>> call.name;
@@ -163,6 +209,14 @@ void Profiler::parseLine(const char* in, Profile* profile)
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) {
@@ -174,6 +228,8 @@ void Profiler::parseLine(const char* in, Profile* profile)
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) {
@@ -183,15 +239,21 @@ void Profiler::parseLine(const char* in, Profile* profile)
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);
diff --git a/common/trace_profiler.hpp b/common/trace_profiler.hpp
index d833242..b0b3bd5 100644
--- a/common/trace_profiler.hpp
+++ b/common/trace_profiler.hpp
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2012 VMware, Inc.
+ * Copyright 2013 Intel, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -45,6 +46,11 @@ struct Profile {
int64_t cpuStart;
int64_t cpuDuration;
+ int64_t vsizeStart;
+ int64_t vsizeDuration;
+ int64_t rssStart;
+ int64_t rssDuration;
+
int64_t pixels;
std::string name;
@@ -59,6 +65,11 @@ struct Profile {
int64_t cpuStart;
int64_t cpuDuration;
+ int64_t vsizeStart;
+ int64_t vsizeDuration;
+ int64_t rssStart;
+ int64_t rssDuration;
+
/* Indices to profile->calls array */
struct {
unsigned begin;
@@ -72,6 +83,8 @@ struct Profile {
uint64_t gpuTotal;
uint64_t cpuTotal;
uint64_t pixelTotal;
+ int64_t vsizeTotal;
+ int64_t rssTotal;
/* Indices to profile->calls array */
std::vector<unsigned> calls;
@@ -88,14 +101,16 @@ public:
Profiler();
~Profiler();
- void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_);
+ void setup(bool cpuTimes_, bool gpuTimes_, bool pixelsDrawn_, bool memoryUsage_);
void addCall(unsigned no,
const char* name,
unsigned program,
int64_t pixels,
int64_t gpuStart, int64_t gpuDuration,
- int64_t cpuStart, int64_t cpuDuration);
+ int64_t cpuStart, int64_t cpuDuration,
+ int64_t vsizeStart, int64_t vsizeDuration,
+ int64_t rssStart, int64_t rssDuration);
void addFrameEnd();
@@ -103,9 +118,13 @@ public:
void setBaseCpuTime(int64_t cpuStart);
void setBaseGpuTime(int64_t gpuStart);
+ void setBaseVsizeUsage(int64_t vsizeStart);
+ void setBaseRssUsage(int64_t rssStart);
int64_t getBaseCpuTime();
int64_t getBaseGpuTime();
+ int64_t getBaseVsizeUsage();
+ int64_t getBaseRssUsage();
static void parseLine(const char* line, Profile* profile);
@@ -113,10 +132,13 @@ private:
int64_t baseGpuTime;
int64_t baseCpuTime;
int64_t minCpuTime;
+ int64_t baseVsizeUsage;
+ int64_t baseRssUsage;
bool cpuTimes;
bool gpuTimes;
bool pixelsDrawn;
+ bool memoryUsage;
};
}
diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt
index b271727..9ea1ae9 100644
--- a/retrace/CMakeLists.txt
+++ b/retrace/CMakeLists.txt
@@ -102,6 +102,9 @@ if (WIN32 OR APPLE OR X11_FOUND)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries (glretrace rt)
+ if (READPROC_H_FOUND)
+ target_link_libraries (glretrace proc)
+ endif ()
endif ()
endif ()
@@ -127,6 +130,9 @@ if (ENABLE_EGL AND X11_FOUND AND NOT WIN32 AND NOT APPLE)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
target_link_libraries (eglretrace rt)
+ if (READPROC_H_FOUND)
+ target_link_libraries (eglretrace proc)
+ endif ()
endif ()
install (TARGETS eglretrace RUNTIME DESTINATION bin)
diff --git a/retrace/glretrace_main.cpp b/retrace/glretrace_main.cpp
index d0298fc..c840335 100755
--- a/retrace/glretrace_main.cpp
+++ b/retrace/glretrace_main.cpp
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2011 Jose Fonseca
+ * Copyright 2013 Shuang He <shuang.he at intel.com>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -31,6 +32,7 @@
#include "glstate.hpp"
#include "glretrace.hpp"
#include "os_time.hpp"
+#include "os_memory.hpp"
/* Synchronous debug output may reduce performance however,
* without it the callNo in the callback may be inaccurate
@@ -59,6 +61,10 @@ struct CallQuery
const trace::FunctionSig *sig;
int64_t cpuStart;
int64_t cpuEnd;
+ int64_t vsizeStart;
+ int64_t vsizeEnd;
+ int64_t rssStart;
+ int64_t rssEnd;
};
static bool supportsElapsed = true;
@@ -137,10 +143,20 @@ getTimeFrequency(void) {
}
}
+static inline void
+getCurrentVsize(int64_t& vsize) {
+ vsize = os::getVsize();
+}
+
+static inline void
+getCurrentRss(int64_t& rss) {
+ rss = os::getRss();
+}
+
static void
completeCallQuery(CallQuery& query) {
/* Get call start and duration */
- int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0;
+ int64_t gpuStart = 0, gpuDuration = 0, cpuDuration = 0, pixels = 0, vsizeDuration = 0, rssDuration = 0;
if (query.isDraw) {
if (retrace::profilingGpuTimes) {
@@ -163,10 +179,15 @@ completeCallQuery(CallQuery& query) {
cpuDuration = query.cpuEnd - query.cpuStart;
}
+ if (retrace::profilingMemoryUsage) {
+ vsizeDuration = query.vsizeEnd - query.vsizeStart;
+ rssDuration = query.rssEnd - query.rssStart;
+ }
+
glDeleteQueries(NUM_QUERIES, query.ids);
/* Add call to profile */
- retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration);
+ retrace::profiler.addCall(query.call, query.sig->name, query.program, pixels, gpuStart, gpuDuration, query.cpuStart, cpuDuration, query.vsizeStart, vsizeDuration, query.rssStart, rssDuration);
}
void
@@ -213,6 +234,12 @@ beginProfile(trace::Call &call, bool isDraw) {
CallQuery& query = callQueries.back();
query.cpuStart = getCurrentTime();
}
+
+ if (retrace::profilingMemoryUsage) {
+ CallQuery& query = callQueries.back();
+ query.vsizeStart = os::getVsize();
+ query.rssStart = os::getRss();
+ }
}
void
@@ -234,6 +261,12 @@ endProfile(trace::Call &call, bool isDraw) {
glEndQuery(GL_SAMPLES_PASSED);
}
}
+
+ if (retrace::profilingMemoryUsage) {
+ CallQuery& query = callQueries.back();
+ query.vsizeEnd = os::getVsize();
+ query.rssEnd = os::getRss();
+ }
}
void
@@ -287,6 +320,14 @@ initContext() {
retrace::profiler.setBaseGpuTime(currentTime);
}
}
+
+ if (retrace::profilingMemoryUsage) {
+ GLint64 currentVsize, currentRss;
+ getCurrentVsize(currentVsize);
+ retrace::profiler.setBaseVsizeUsage(currentVsize);
+ getCurrentRss(currentRss);
+ retrace::profiler.setBaseRssUsage(currentRss);
+ }
}
void
diff --git a/retrace/retrace.hpp b/retrace/retrace.hpp
index 7c8dcd5..5599b37 100644
--- a/retrace/retrace.hpp
+++ b/retrace/retrace.hpp
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2011-2012 Jose Fonseca
+ * Copyright 2013 Shuang He <shuang.he at intel.com>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -92,6 +93,7 @@ extern bool profiling;
extern bool profilingCpuTimes;
extern bool profilingGpuTimes;
extern bool profilingPixelsDrawn;
+extern bool profilingMemoryUsage;
/**
* State dumping.
diff --git a/retrace/retrace_main.cpp b/retrace/retrace_main.cpp
index ca03745..9909fec 100644
--- a/retrace/retrace_main.cpp
+++ b/retrace/retrace_main.cpp
@@ -1,6 +1,7 @@
/**************************************************************************
*
* Copyright 2011 Jose Fonseca
+ * Copyright 2013 Shuang He <shuang.he at intel.com>
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -72,6 +73,7 @@ bool profiling = false;
bool profilingGpuTimes = false;
bool profilingCpuTimes = false;
bool profilingPixelsDrawn = false;
+bool profilingMemoryUsage = false;
bool useCallNos = true;
unsigned frameNo = 0;
@@ -514,6 +516,7 @@ usage(const char *argv0) {
" --pcpu cpu profiling (cpu times per call)\n"
" --pgpu gpu profiling (gpu times per draw call)\n"
" --ppd pixels drawn profiling (pixels drawn per draw call)\n"
+ " --pmem memory usage profiling (vsize rss per call)\n"
" -c, --compare=PREFIX compare against snapshots with given PREFIX\n"
" -C, --calls=CALLSET calls to compare (default is every frame)\n"
" --call-nos[=BOOL] use call numbers in snapshot filenames\n"
@@ -536,6 +539,7 @@ enum {
PCPU_OPT,
PGPU_OPT,
PPD_OPT,
+ PMEM_OPT,
SB_OPT,
};
@@ -556,6 +560,7 @@ longOptions[] = {
{"pcpu", no_argument, 0, PCPU_OPT},
{"pgpu", no_argument, 0, PGPU_OPT},
{"ppd", no_argument, 0, PPD_OPT},
+ {"pmem", no_argument, 0, PMEM_OPT},
{"sb", no_argument, 0, SB_OPT},
{"snapshot-prefix", required_argument, 0, 's'},
{"snapshot", required_argument, 0, 'S'},
@@ -676,6 +681,13 @@ int main(int argc, char **argv)
retrace::profilingPixelsDrawn = true;
break;
+ case PMEM_OPT:
+ retrace::debug = false;
+ retrace::profiling = true;
+ retrace::verbosity = -1;
+
+ retrace::profilingMemoryUsage = true;
+ break;
default:
std::cerr << "error: unknown option " << opt << "\n";
usage(argv[0]);
@@ -685,7 +697,7 @@ int main(int argc, char **argv)
retrace::setUp();
if (retrace::profiling) {
- retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn);
+ retrace::profiler.setup(retrace::profilingCpuTimes, retrace::profilingGpuTimes, retrace::profilingPixelsDrawn, retrace::profilingMemoryUsage);
}
os::setExceptionCallback(exceptionCallback);
--
1.7.10.1
More information about the apitrace
mailing list