diff --git a/server/TracyPopcnt.hpp b/server/TracyPopcnt.hpp new file mode 100644 index 00000000..d6e4af03 --- /dev/null +++ b/server/TracyPopcnt.hpp @@ -0,0 +1,17 @@ +#ifndef __TRACYPOPCNT_HPP__ +#define __TRACYPOPCNT_HPP__ + +#ifdef _MSC_VER +# include +# define TracyCountBits __popcnt64 +#else +static int TracyCountBits( uint64_t i ) +{ + i = i - ( (i >> 1) & 0x5555555555555555 ); + i = ( i & 0x3333333333333333 ) + ( (i >> 2) & 0x3333333333333333 ); + i = ( (i + (i >> 4) ) & 0x0F0F0F0F0F0F0F0F ); + return ( i * (0x0101010101010101) ) >> 56; +} +#endif + +#endif diff --git a/server/TracyVector.hpp b/server/TracyVector.hpp index 3567d6cb..93542fdb 100644 --- a/server/TracyVector.hpp +++ b/server/TracyVector.hpp @@ -5,6 +5,7 @@ #include #include "TracyMemory.hpp" +#include "TracyPopcnt.hpp" namespace tracy { @@ -13,6 +14,7 @@ namespace tracy template using Vector = std::vector; #else +#pragma pack( 1 ) template class Vector { @@ -20,10 +22,11 @@ public: using iterator = T*; Vector() - : m_ptr( nullptr ) + : m_ptr( new T[1] ) , m_size( 0 ) , m_capacity( 0 ) { + memUsage.fetch_add( sizeof( T ), std::memory_order_relaxed ); } Vector( const Vector& ) = delete; @@ -37,7 +40,7 @@ public: ~Vector() { - memUsage.fetch_sub( m_capacity * sizeof( T ), std::memory_order_relaxed ); + memUsage.fetch_sub( Capacity() * sizeof( T ), std::memory_order_relaxed ); delete[] m_ptr; } @@ -73,13 +76,13 @@ public: void push_back( const T& v ) { - if( m_size == m_capacity ) AllocMore(); + if( m_size == Capacity() ) AllocMore(); m_ptr[m_size++] = v; } void push_back( T&& v ) { - if( m_size == m_capacity ) AllocMore(); + if( m_size == Capacity() ) AllocMore(); m_ptr[m_size++] = std::move( v ); } @@ -87,7 +90,7 @@ public: { assert( it >= m_ptr && it <= m_ptr + m_size ); const auto dist = it - m_ptr; - if( m_size == m_capacity ) AllocMore(); + if( m_size == Capacity() ) AllocMore(); if( dist != m_size ) memmove( m_ptr + dist + 1, m_ptr + dist, ( m_size - dist ) * sizeof( T ) ); m_size++; m_ptr[dist] = v; @@ -98,7 +101,7 @@ public: { assert( it >= m_ptr && it <= m_ptr + m_size ); const auto dist = it - m_ptr; - if( m_size == m_capacity ) AllocMore(); + if( m_size == Capacity() ) AllocMore(); if( dist != m_size ) memmove( m_ptr + dist + 1, m_ptr + dist, ( m_size - dist ) * sizeof( T ) ); m_size++; m_ptr[dist] = std::move( v ); @@ -110,7 +113,7 @@ public: assert( it >= m_ptr && it <= m_ptr + m_size ); const auto sz = end - begin; const auto dist = it - m_ptr; - while( m_size + sz > m_capacity ) AllocMore(); + while( m_size + sz > Capacity() ) AllocMore(); if( dist != m_size ) memmove( m_ptr + dist + sz, m_ptr + dist, ( m_size - dist ) * sizeof( T ) ); m_size += sz; memcpy( m_ptr + dist, begin, sz * sizeof( T ) ); @@ -133,8 +136,15 @@ public: void reserve( size_t cap ) { - if( cap <= m_capacity ) return; - memUsage.fetch_add( ( cap - m_capacity ) * sizeof( T ), std::memory_order_relaxed ); + if( cap <= Capacity() ) return; + cap--; + cap |= cap >> 1; + cap |= cap >> 2; + cap |= cap >> 4; + cap |= cap >> 8; + cap |= cap >> 16; + cap = TracyCountBits( cap ); + memUsage.fetch_add( ( ( 1 << cap ) - Capacity() ) * sizeof( T ), std::memory_order_relaxed ); m_capacity = cap; Realloc(); } @@ -147,22 +157,14 @@ public: private: void AllocMore() { - if( m_capacity == 0 ) - { - m_capacity = 1; - memUsage.fetch_add( m_capacity * sizeof( T ), std::memory_order_relaxed ); - } - else - { - memUsage.fetch_add( m_capacity * sizeof( T ), std::memory_order_relaxed ); - m_capacity *= 2; - } + memUsage.fetch_add( Capacity() * sizeof( T ), std::memory_order_relaxed ); + m_capacity++; Realloc(); } void Realloc() { - T* ptr = new T[m_capacity]; + T* ptr = new T[Capacity()]; if( m_size != 0 ) { memcpy( ptr, m_ptr, m_size * sizeof( T ) ); @@ -171,10 +173,16 @@ private: m_ptr = ptr; } + uint32_t Capacity() const + { + return 1 << m_capacity; + } + T* m_ptr; uint32_t m_size; - uint32_t m_capacity; + uint8_t m_capacity; }; +#pragma pack() #endif } diff --git a/server/TracyView.cpp b/server/TracyView.cpp index cc235003..677a655e 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -19,25 +19,13 @@ #include "TracyFileRead.hpp" #include "TracyFileWrite.hpp" #include "TracyImGui.hpp" +#include "TracyPopcnt.hpp" #include "TracyView.hpp" #ifdef TRACY_FILESELECTOR # include "../nfd/nfd.h" #endif -#ifdef _MSC_VER -# include -# define CountBits __popcnt64 -#else -static int CountBits( uint64_t i ) -{ - i = i - ( (i >> 1) & 0x5555555555555555 ); - i = ( i & 0x3333333333333333 ) + ( (i >> 2) & 0x3333333333333333 ); - i = ( (i + (i >> 4) ) & 0x0F0F0F0F0F0F0F0F ); - return ( i * (0x0101010101010101) ) >> 56; -} -#endif - namespace tracy { @@ -2505,11 +2493,11 @@ int View::DrawLocks( uint64_t tid, bool hover, double pxns, const ImVec2& wpos, { if( (*vbegin)->lockCount == 1 ) { - ImGui::Text( "Thread \"%s\" has lock. Blocked threads (%i):", GetThreadString( tid ), CountBits( (*vbegin)->waitList ) ); + ImGui::Text( "Thread \"%s\" has lock. Blocked threads (%i):", GetThreadString( tid ), TracyCountBits( (*vbegin)->waitList ) ); } else { - ImGui::Text( "Thread \"%s\" has %i locks. Blocked threads (%i):", GetThreadString( tid ), (*vbegin)->lockCount, CountBits( (*vbegin)->waitList ) ); + ImGui::Text( "Thread \"%s\" has %i locks. Blocked threads (%i):", GetThreadString( tid ), (*vbegin)->lockCount, TracyCountBits( (*vbegin)->waitList ) ); } auto waitList = (*vbegin)->waitList; int t = 0; diff --git a/standalone/build/win32/Tracy.vcxproj b/standalone/build/win32/Tracy.vcxproj index 58357300..27b02f40 100644 --- a/standalone/build/win32/Tracy.vcxproj +++ b/standalone/build/win32/Tracy.vcxproj @@ -112,6 +112,7 @@ + diff --git a/standalone/build/win32/Tracy.vcxproj.filters b/standalone/build/win32/Tracy.vcxproj.filters index 9d5bfb50..666b1ea6 100644 --- a/standalone/build/win32/Tracy.vcxproj.filters +++ b/standalone/build/win32/Tracy.vcxproj.filters @@ -140,5 +140,8 @@ server + + server + \ No newline at end of file