From: Shuang He Date: Mon, 18 Feb 2013 02:09:44 +0000 (+0800) Subject: Extend profiling tool to support Vsize and Rss memory usage profile per call X-Git-Url: https://git.cworth.org/git?p=apitrace;a=commitdiff_plain;h=4f9982f5ec3dccae65d5a49dfd5a81b9737d90cd Extend profiling tool to support Vsize and Rss memory usage profile per call Add one new option -pmem for retrace tool to track Visze and Rss usage during every call Signed-off-by: Shuang He Signed-off-by: José Fonseca --- 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..4774412 --- /dev/null +++ b/common/os_memory.hpp @@ -0,0 +1,67 @@ +/************************************************************************** + * + * Copyright (C) 2013 Intel Corporation. All rights reversed. + * Author: Shuang He + * 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 + +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..773e7cc 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..e3ae016 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 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 f369b33..1591287 100755 --- a/retrace/glretrace_main.cpp +++ b/retrace/glretrace_main.cpp @@ -1,6 +1,8 @@ /************************************************************************** * * Copyright 2011 Jose Fonseca + * Copyright (C) 2013 Intel Corporation. All rights reversed. + * Author: Shuang He * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -31,6 +33,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 @@ -60,6 +63,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; @@ -138,10 +145,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) { @@ -164,10 +181,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 @@ -214,6 +236,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 @@ -235,6 +263,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 @@ -289,6 +323,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..14317cf 100644 --- a/retrace/retrace.hpp +++ b/retrace/retrace.hpp @@ -1,6 +1,8 @@ /************************************************************************** * * Copyright 2011-2012 Jose Fonseca + * Copyright (C) 2013 Intel Corporation. All rights reversed. + * Author: Shuang He * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -92,6 +94,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..7cc3fca 100644 --- a/retrace/retrace_main.cpp +++ b/retrace/retrace_main.cpp @@ -1,6 +1,8 @@ /************************************************************************** * * Copyright 2011 Jose Fonseca + * Copyright (C) 2013 Intel Corporation. All rights reversed. + * Author: Shuang He * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -72,6 +74,7 @@ bool profiling = false; bool profilingGpuTimes = false; bool profilingCpuTimes = false; bool profilingPixelsDrawn = false; +bool profilingMemoryUsage = false; bool useCallNos = true; unsigned frameNo = 0; @@ -514,6 +517,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 +540,7 @@ enum { PCPU_OPT, PGPU_OPT, PPD_OPT, + PMEM_OPT, SB_OPT, }; @@ -556,6 +561,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 +682,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 +698,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);