Path: blob/21.2-virgl/src/gallium/drivers/swr/rasterizer/common/rdtsc_buckets.cpp
4574 views
/****************************************************************************1* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*22* @file rdtsc_buckets.cpp23*24* @brief implementation of rdtsc buckets.25*26* Notes:27*28******************************************************************************/29#include "rdtsc_buckets.h"30#include <inttypes.h>3132#if defined(_WIN32)33#define PATH_SEPARATOR "\\"34#elif defined(__unix__) || defined(__APPLE__)35#define PATH_SEPARATOR "/"36#else37#error "Unsupported platform"38#endif3940THREAD UINT tlsThreadId = 0;4142BucketManager::~BucketManager()43{44}4546void BucketManager::RegisterThread(const std::string& name)47{4849BUCKET_THREAD newThread;50newThread.name = name;51newThread.root.children.reserve(mBuckets.size());52newThread.root.id = 0;53newThread.root.pParent = nullptr;54newThread.pCurrent = &newThread.root;5556mThreadMutex.lock();5758// assign unique thread id for this thread59size_t id = mThreads.size();60newThread.id = (UINT)id;61tlsThreadId = (UINT)id;6263// store new thread64mThreads.push_back(newThread);6566mThreadMutex.unlock();67}6869UINT BucketManager::RegisterBucket(const BUCKET_DESC& desc)70{71mThreadMutex.lock();72size_t id = mBuckets.size();73mBuckets.push_back(desc);74mThreadMutex.unlock();75return (UINT)id;76}7778void BucketManager::PrintBucket(79FILE* f, UINT level, uint64_t threadCycles, uint64_t parentCycles, const BUCKET& bucket)80{81const char* arrows[] = {82"",83"|-> ",84" |-> ",85" |-> ",86" |-> ",87" |-> ",88" |-> ",89" |-> ",90" |-> ",91};9293// compute percent of total cycles used by this bucket94float percentTotal = (float)((double)bucket.elapsed / (double)threadCycles * 100.0);9596// compute percent of parent cycles used by this bucket97float percentParent = (float)((double)bucket.elapsed / (double)parentCycles * 100.0);9899// compute average cycle count per invocation100uint64_t CPE = bucket.elapsed / bucket.count;101102BUCKET_DESC& desc = mBuckets[bucket.id];103104// construct hierarchy visualization105std::string str = arrows[level];106str += desc.name;107char hier[80];108strcpy_s(hier, sizeof(hier)-1, str.c_str());109110// print out111fprintf(f,112"%6.2f %6.2f %-10" PRIu64 " %-10" PRIu64 " %-10u %-10lu %-10u %s\n",113percentTotal,114percentParent,115bucket.elapsed,116CPE,117bucket.count,118(unsigned long)0,119(uint32_t)0,120hier);121122// dump all children of this bucket123for (const BUCKET& child : bucket.children)124{125if (child.count)126{127PrintBucket(f, level + 1, threadCycles, bucket.elapsed, child);128}129}130}131132void BucketManager::PrintThread(FILE* f, const BUCKET_THREAD& thread)133{134// print header135fprintf(f, "\nThread %u (%s)\n", thread.id, thread.name.c_str());136fprintf(f, " %%Tot %%Par Cycles CPE NumEvent CPE2 NumEvent2 Bucket\n");137138// compute thread level total cycle counts across all buckets from root139const BUCKET& root = thread.root;140uint64_t totalCycles = 0;141for (const BUCKET& child : root.children)142{143totalCycles += child.elapsed;144}145146for (const BUCKET& child : root.children)147{148if (child.count)149{150PrintBucket(f, 0, totalCycles, totalCycles, child);151}152}153}154155void BucketManager::PrintReport(const std::string& filename)156{157{158FILE* f = fopen(filename.c_str(), "w");159assert(f);160161mThreadMutex.lock();162for (const BUCKET_THREAD& thread : mThreads)163{164PrintThread(f, thread);165fprintf(f, "\n");166}167168mThreadMutex.unlock();169170fclose(f);171}172}173174175void BucketManager::StartCapture()176{177178printf("Capture Starting\n");179180mCapturing = true;181}182183void BucketManager_StartBucket(BucketManager* pBucketMgr, uint32_t id)184{185pBucketMgr->StartBucket(id);186}187188void BucketManager_StopBucket(BucketManager* pBucketMgr, uint32_t id)189{190pBucketMgr->StopBucket(id);191}192193194