mirror of
https://github.com/wolfpld/tracy.git
synced 2025-03-20 07:40:02 +08:00
Store source location in a single object.
Source file, function name and line number are now stored in a const static container object. This has the following benefits: - Slightly lighter profiling workload (3 instructions less). - Profiling queue event size is significantly reduced, by 12 bytes. This has an effect on all queue event types. - Source location grouping has now no cost, as it's performed at the compilation stage. This allows simplification of server code. The downside is that the full source location resolution is now performed in two steps, as the server has to query both source location container and strings contained within. This has almost no real impact on profiler operation.
This commit is contained in:
@@ -10,7 +10,7 @@ struct Event
|
||||
{
|
||||
int64_t start;
|
||||
int64_t end;
|
||||
uint32_t srcloc;
|
||||
uint64_t srcloc;
|
||||
uint32_t color;
|
||||
|
||||
Event* parent;
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
#ifndef __TRACYSOURCELOCATION_HPP__
|
||||
#define __TRACYSOURCELOCATION_HPP__
|
||||
|
||||
#include <functional>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace tracy
|
||||
{
|
||||
|
||||
struct SourceLocation
|
||||
{
|
||||
uint64_t filename;
|
||||
uint64_t function;
|
||||
uint32_t line;
|
||||
|
||||
struct Hasher
|
||||
{
|
||||
size_t operator()( const SourceLocation& v ) const
|
||||
{
|
||||
const static std::hash<uint64_t> hash;
|
||||
return hash( v.filename ) ^ hash( v.function ) ^ hash( v.line );
|
||||
}
|
||||
};
|
||||
|
||||
struct Comparator
|
||||
{
|
||||
bool operator()( const SourceLocation& lhs, const SourceLocation& rhs ) const
|
||||
{
|
||||
return memcmp( &lhs, &rhs, sizeof( SourceLocation ) ) == 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+41
-19
@@ -219,6 +219,9 @@ void View::Process( const QueueItem& ev )
|
||||
case QueueType::FrameMark:
|
||||
ProcessFrameMark( ev.hdr.id );
|
||||
break;
|
||||
case QueueType::SourceLocation:
|
||||
AddSourceLocation( ev.hdr.id, ev.srcloc );
|
||||
break;
|
||||
default:
|
||||
assert( false );
|
||||
break;
|
||||
@@ -230,27 +233,14 @@ void View::ProcessZoneBegin( uint64_t id, const QueueZoneBegin& ev )
|
||||
auto it = m_pendingEndZone.find( id );
|
||||
auto zone = m_slab.Alloc<Event>();
|
||||
|
||||
CheckString( ev.filename );
|
||||
CheckString( ev.function );
|
||||
CheckSourceLocation( ev.srcloc );
|
||||
CheckThreadString( ev.thread );
|
||||
|
||||
zone->start = ev.time * m_timerMul;
|
||||
zone->srcloc = ev.srcloc;
|
||||
zone->color = ev.color;
|
||||
|
||||
SourceLocation srcloc { ev.filename, ev.function, ev.line };
|
||||
auto lit = m_locationRef.find( srcloc );
|
||||
|
||||
std::unique_lock<std::mutex> lock( m_lock );
|
||||
if( lit == m_locationRef.end() )
|
||||
{
|
||||
const auto ref = uint32_t( m_srcFile.size() );
|
||||
zone->srcloc = ref;
|
||||
m_locationRef.emplace( srcloc, ref );
|
||||
m_srcFile.push_back( srcloc );
|
||||
}
|
||||
else
|
||||
{
|
||||
zone->srcloc = lit->second;
|
||||
}
|
||||
|
||||
if( it == m_pendingEndZone.end() )
|
||||
{
|
||||
@@ -331,6 +321,18 @@ void View::CheckThreadString( uint64_t id )
|
||||
m_sock.Send( &id, sizeof( id ) );
|
||||
}
|
||||
|
||||
void View::CheckSourceLocation( uint64_t ptr )
|
||||
{
|
||||
if( m_sourceLocation.find( ptr ) != m_sourceLocation.end() ) return;
|
||||
if( m_pendingSourceLocation.find( ptr ) != m_pendingSourceLocation.end() ) return;
|
||||
|
||||
m_pendingSourceLocation.emplace( ptr );
|
||||
|
||||
uint8_t type = ServerQuerySourceLocation;
|
||||
m_sock.Send( &type, sizeof( type ) );
|
||||
m_sock.Send( &ptr, sizeof( ptr ) );
|
||||
}
|
||||
|
||||
void View::AddString( uint64_t ptr, std::string&& str )
|
||||
{
|
||||
assert( m_strings.find( ptr ) == m_strings.end() );
|
||||
@@ -351,6 +353,17 @@ void View::AddThreadString( uint64_t id, std::string&& str )
|
||||
m_threadNames.emplace( id, std::move( str ) );
|
||||
}
|
||||
|
||||
void View::AddSourceLocation( uint64_t ptr, const QueueSourceLocation& srcloc )
|
||||
{
|
||||
assert( m_sourceLocation.find( ptr ) == m_sourceLocation.end() );
|
||||
auto it = m_pendingSourceLocation.find( ptr );
|
||||
assert( it != m_pendingSourceLocation.end() );
|
||||
m_pendingSourceLocation.erase( it );
|
||||
CheckString( srcloc.file );
|
||||
CheckString( srcloc.function );
|
||||
std::lock_guard<std::mutex> lock( m_lock );
|
||||
m_sourceLocation.emplace( ptr, srcloc );
|
||||
}
|
||||
|
||||
void View::NewZone( Event* zone, uint64_t thread )
|
||||
{
|
||||
@@ -1043,8 +1056,17 @@ int View::DrawZoneLevel( const Vector<Event*>& vec, bool hover, double pxns, con
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto& srcFile = m_srcFile[ev.srcloc];
|
||||
const char* func = GetString( srcFile.function );
|
||||
const char* func = "???";
|
||||
const char* filename = "???";
|
||||
uint32_t line = 0;
|
||||
auto srcit = m_sourceLocation.find( ev.srcloc );
|
||||
if( srcit != m_sourceLocation.end() )
|
||||
{
|
||||
func = GetString( srcit->second.function );
|
||||
filename = GetString( srcit->second.file );
|
||||
line = srcit->second.line;
|
||||
}
|
||||
|
||||
const auto tsz = ImGui::CalcTextSize( func );
|
||||
const auto pr0 = ( ev.start - m_zvStart ) * pxns;
|
||||
const auto pr1 = ( end - m_zvStart ) * pxns;
|
||||
@@ -1082,7 +1104,7 @@ int View::DrawZoneLevel( const Vector<Event*>& vec, bool hover, double pxns, con
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text( "%s", func );
|
||||
ImGui::Text( "%s:%i", GetString( srcFile.filename ), srcFile.line );
|
||||
ImGui::Text( "%s:%i", filename, line );
|
||||
ImGui::Text( "Execution time: %s", TimeToString( end - ev.start ) );
|
||||
ImGui::Text( "Without profiling: %s", TimeToString( end - ev.start - m_delay ) );
|
||||
ImGui::EndTooltip();
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "../common/TracyQueue.hpp"
|
||||
#include "TracyEvent.hpp"
|
||||
#include "TracySlab.hpp"
|
||||
#include "TracySourceLocation.hpp"
|
||||
#include "TracyVector.hpp"
|
||||
|
||||
struct ImVec2;
|
||||
@@ -53,8 +52,11 @@ private:
|
||||
|
||||
void CheckString( uint64_t ptr );
|
||||
void CheckThreadString( uint64_t id );
|
||||
void CheckSourceLocation( uint64_t ptr );
|
||||
|
||||
void AddString( uint64_t ptr, std::string&& str );
|
||||
void AddThreadString( uint64_t id, std::string&& str );
|
||||
void AddSourceLocation( uint64_t id, const QueueSourceLocation& srcloc );
|
||||
|
||||
void NewZone( Event* zone, uint64_t thread );
|
||||
void UpdateZone( Event* zone );
|
||||
@@ -87,10 +89,10 @@ private:
|
||||
// this block must be locked
|
||||
std::mutex m_lock;
|
||||
Vector<uint64_t> m_frames;
|
||||
Vector<SourceLocation> m_srcFile;
|
||||
Vector<ThreadData> m_threads;
|
||||
std::unordered_map<uint64_t, std::string> m_strings;
|
||||
std::unordered_map<uint64_t, std::string> m_threadNames;
|
||||
std::unordered_map<uint64_t, QueueSourceLocation> m_sourceLocation;
|
||||
uint64_t m_zonesCnt;
|
||||
|
||||
std::mutex m_mbpslock;
|
||||
@@ -101,7 +103,7 @@ private:
|
||||
std::unordered_map<uint64_t, Event*> m_openZones;
|
||||
std::unordered_set<uint64_t> m_pendingStrings;
|
||||
std::unordered_set<uint64_t> m_pendingThreads;
|
||||
std::unordered_map<SourceLocation, uint32_t, SourceLocation::Hasher, SourceLocation::Comparator> m_locationRef;
|
||||
std::unordered_set<uint64_t> m_pendingSourceLocation;
|
||||
std::unordered_map<uint64_t, uint32_t> m_threadMap;
|
||||
|
||||
Slab<EventSize*1024*1024> m_slab;
|
||||
|
||||
Reference in New Issue
Block a user