// ======================================================================== // // Copyright 2009-2014 Intel Corporation // // // // Licensed under the Apache License, Version 2.0 (the "License"); // // you may not use this file except in compliance with the License. // // You may obtain a copy of the License at // // // // http://www.apache.org/licenses/LICENSE-2.0 // // // // Unless required by applicable law or agreed to in writing, software // // distributed under the License is distributed on an "AS IS" BASIS, // // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // // See the License for the specific language governing permissions and // // limitations under the License. // // ======================================================================== // #include "tasklogger.h" #include "sys/sysinfo.h" #include "math/math.h" #include "math/vec2.h" #include "math/bbox.h" #include #include "string.h" namespace embree { bool TaskLogger::active = false; int64 TaskLogger::startCycle = 0; std::vector TaskLogger::threads; bool TaskLogger::init (size_t numThreads) { #if defined(RTCORE_TASKLOGGER) if (threads.size() != numThreads) { threads.clear(); for (size_t i=0; ireset(); startCycle = rdtsc(); active = true; #endif } void TaskLogger::stop() { #if defined(RTCORE_TASKLOGGER) active = false; #endif } namespace DRAW { int Black = 0; int Blue = 1; int Green = 2; int Cyan = 3; int Red = 4; int Magenta = 5; int Yellow = 6; int White = 7; int DarkBlue = 8; class Drawing { public: Drawing(const char* file) { id = 0; fout.open (file); fout << "#FIG 3.2" << "\n"; fout << "# Created by Embree" << "\n"; fout << "# METADATA 1.0" << "\n"; fout << "Portrait" << "\n"; fout << "Flush left" << "\n"; fout << "Metric" << "\n"; fout << "A4" << "\n"; fout << "100.00" << "\n"; fout << "Single" << "\n"; fout << "-2" << "\n"; fout << "1200 2" << "\n"; ofsX = 0; ofsY = 0; scaleX = 500; scaleY = 500; } void drawNamedBox(const char* name, Vec2f a, Vec2f b, int fillColor, int thickness = 0, int borderColor = Black) { fout << "# METADATA " << id++ << "" << "\n"; if (name) fout << "# " << name << "\n"; const int fillBrightness = 20; fout << "2 2 0 " << thickness << " " << borderColor << " " << fillColor << " 50 0 " << fillBrightness << " 4.000 2 0 7 0 0 5" << "\n"; const int x0 = int(scaleX * a.x + ofsX); const int y0 = int(scaleY * a.y + ofsY); const int x1 = int(scaleX * b.x + ofsX); const int y1 = int(scaleY * b.y + ofsY); fout << " "; fout << x0 << " " << y0 << " "; fout << x1 << " " << y0 << " "; fout << x1 << " " << y1 << " "; fout << x0 << " " << y1 << " "; fout << x0 << " " << y0 << "\n"; } void drawBox(Vec2f a, Vec2f b, int fillColor, int thickness = 0, int borderColor = Black) { drawNamedBox(NULL, a, b, fillColor, thickness, borderColor) ; } void drawText(Vec2f p, const char* text, int size, int color) { fout << "# METADATA " << id++ << "" << "\n"; const int x0 = int(scaleX * p.x + ofsX); const int y0 = int(scaleY * p.y + ofsY); fout << "4 0 " << color << " 50 0 0 " << size << " 0.0000 3 873 150 " << x0 << " " << y0 << " " << text << "\\001" << "\n"; } void drawPolyLine(Vec2f* points, int numPoints, int size, int color) { fout << "# METADATA " << id++ << "" << "\n"; fout << "2 1 0 2 0 7 50 0 -1 4.000 2 0 0 0 0 " << numPoints << "\n"; for (int i=0; i" << id++ << "" << "\n"; fout << "2 1 0 2 0 7 50 0 -1 4.000 2 0 0 1 0 2" << "\n"; fout << "1 1 2.00 120.00 240.00" << "\n"; const int x0 = int(scaleX * a.x + ofsX); const int y0 = int(scaleY * a.y + ofsY); const int x1 = int(scaleX * b.x + ofsX); const int y1 = int(scaleY * b.y + ofsY); fout << x0 << " " << y0 << " "; fout << x1 << " " << y1 << "\n"; } void drawLine(Vec2f a, Vec2f b, int color) { fout << "# METADATA " << id++ << "" << "\n"; fout << "2 1 0 2 0 7 50 0 -1 4.000 2 0 0 0 0 2" << "\n"; const int x0 = int(scaleX * a.x + ofsX); const int y0 = int(scaleY * a.y + ofsY); const int x1 = int(scaleX * b.x + ofsX); const int y1 = int(scaleY * b.y + ofsY); fout << x0 << " " << y0 << " "; fout << x1 << " " << y1 << "\n"; } ~Drawing() { fout.close(); } public: int id; float ofsX, ofsY; float scaleX, scaleY; std::ofstream fout; }; } /** store all logged data into FIG file */ void TaskLogger::store(const char* fname) { #if defined(RTCORE_TASKLOGGER) /** generate xfig drawing */ const int64 xAxisStepSize = 1000000000; const char* xAxisUnit = "B"; const int textSize = 8; const int lineSize = 12; BBox2f box; DRAW::Drawing sheet(fname); // DIN A4: width 21cm, height 29.7cm /** find start and end cycle */ int64 minCycle = ((int64) 1) << 62; int64 maxCycle = 0; for (size_t i=0; icurTask; j++) { minCycle = min(minCycle,threads[i]->counters[j].start); maxCycle = max(maxCycle,threads[i]->counters[j].stop); } } minCycle = 0; //int64 dCycle = 900000000; int64 dCycle = max(maxCycle - minCycle, 1LL); // to avoid div by 0 /** compute usage and bandwidth statistics */ const unsigned numUsage = 1024; int64 usedCycles[numUsage]; for (size_t i=0; icurTask; j++) { int64 startCycle = threads[i]->counters[j].start; int64 endCycle = threads[i]->counters[j].stop; for (unsigned b=0; b 0) usedCycles[b] += overlap; } } } /** compute time scale */ box.lower = Vec2f(3.0f,1.0f); box.upper = Vec2f(18.0f,17.0f); float scaleX = (box.upper.x-box.lower.x) / dCycle; float ofsX = box.lower.x - scaleX * minCycle; size_t numThreads = threads.size(); /** draw task scheduling */ float dy = min(1.0f,(box.upper.y-box.lower.y) / threads.size()); for (size_t tid=0; tidcurTask; j++) { float t0 = scaleX * counters->counters[j].start + ofsX; float t1 = scaleX * counters->counters[j].stop + ofsX; int fillColor = DRAW::White; const char* name = counters->counters[j].name; if (name == NULL) name = "NULL"; /*else if (!strcmp(name,"build::primrefgen")) fillColor = DRAW::Blue; else if (!strcmp(name,"build::full")) fillColor = DRAW::Blue; else if (!strcmp(name,"build::split")) fillColor = DRAW::Yellow; else if (!strcmp(name,"build::parsplit")) fillColor = DRAW::Yellow;*/ if (!strcmp(name,"parallel_binning")) fillColor = DRAW::Blue; else if (!strcmp(name,"parallel_partition")) fillColor = DRAW::Blue; else if (!strcmp(name,"toplevel_open_parallel")) fillColor = DRAW::Blue; else if (!strcmp(name,"toplevel_build_subtrees")) fillColor = DRAW::Blue; else if (!strcmp(name,"toplevel_build_parallel")) fillColor = DRAW::Blue; else if (!strcmp(name,"build_parallel_morton")) fillColor = DRAW::Red; else if (!strcmp(name,"scene_build")) fillColor = DRAW::Black; else if (!strcmp(name,"BVH4Refit::sequential")) fillColor = DRAW::Blue; else if (!strcmp(name,"BVH4Refit::parallel")) fillColor = DRAW::DarkBlue; else if (!strcmp(name,"ISPCTask")) fillColor = DRAW::Green; else { fillColor = DRAW::Black; } if (counters->counters[j].elt == size_t(-1)) fillColor = DRAW::Black; char taskName[256]; sprintf(taskName,"%s : %i",name,(int)counters->counters[j].elt); sheet.drawNamedBox(taskName,Vec2f(t0,top),Vec2f(t1,bottom),fillColor); //,1); } } sheet.drawLine(Vec2f(box.lower.x,box.lower.y),Vec2f(box.lower.x,box.upper.y),DRAW::Black); /** draw usage diagram */ box.lower = Vec2f(3.0f,22.0f); box.upper = Vec2f(18.0f,18.0f); Vec2f points[numUsage]; for (unsigned i=0; i