1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00

Consistently print fixed-width percentages.

This commit is contained in:
Benoit Jacob 2022-05-04 16:02:07 +00:00
parent f4581c398c
commit a27d23524c
2 changed files with 71 additions and 90 deletions

View File

@ -26,6 +26,7 @@
#include <stdint.h>
#include <string.h>
#include <cmath>
#include "../common/TracyForceInline.hpp"
@ -77,6 +78,42 @@ static tracy_force_inline void RealToStringInteger( char* buf, char* end )
}
}
template<typename T>
int DigitsLeftOfDecimalPoint( T val ) {
int digits = 1;
T absVal = std::abs( val );
T maxAbsValForCurrentDigits = 10;
while( absVal >= maxAbsValForCurrentDigits ) {
++digits;
maxAbsValForCurrentDigits *= static_cast<T>( 10 );
}
return digits;
}
template<typename T>
int CharsLeftOfDecimalPoint( T val ) {
int extraChars = std::signbit( val ) ? 1 : 0;
return extraChars + DigitsLeftOfDecimalPoint( val );
}
template<typename T>
int DigitsRightOfDecimalPoint( T val, int maxChars ) {
int charsLeftOfPoint = CharsLeftOfDecimalPoint( val );
if( charsLeftOfPoint > maxChars ) {
fprintf( stderr, "Maximum of %d chars is insufficient to print value %g\n",
maxChars, val );
abort();
}
if ( charsLeftOfPoint == maxChars ) {
// maxChars is just large enough for the integer part, no room left for
// a decimal point.
return 0;
} else {
assert( charsLeftOfPoint < maxChars );
return maxChars - 1 - charsLeftOfPoint;
}
}
}
template<typename T>
@ -99,6 +136,28 @@ static inline char* PrintFloat( char* begin, char* end, T value )
#endif
}
// Similar to PrintFloat, but prints exactly `fixedWidth` characters,
// right-justified.
template<typename T>
char* PrintFloatFixedWidth( char* begin, char* end, T value, int fixedWidth ) {
int digitsRight = detail::DigitsRightOfDecimalPoint( value, fixedWidth );
char buf[32];
char* bufEnd = buf + sizeof buf;
char* printEnd = PrintFloat( buf, bufEnd, value, digitsRight );
int width = printEnd - buf;
assert( width <= fixedWidth );
char* dstPtr = begin;
for( int i = width; i < fixedWidth; ++i ) {
assert( end > begin );
*dstPtr++ = ' ';
}
assert( end > dstPtr + width );
memcpy( dstPtr, buf, width );
dstPtr += width;
assert(dstPtr == begin + fixedWidth);
return dstPtr;
}
#ifndef NO_CHARCONV
template<typename T>
static inline const char* RealToString( T val )

View File

@ -2873,6 +2873,14 @@ static bool PrintPercentage( float val, uint32_t col = 0xFFFFFFFF )
return ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect( wpos, wpos + ImVec2( stw * 7, ty ) );
}
static void PrintPercentageUnformattedFixedWidth( float val, uint32_t col )
{
char buf[16];
char *afterFloat = PrintFloatFixedWidth( buf, buf + sizeof buf, val, 4 );
memcpy( afterFloat, "% ", 3 );
TextColoredUnformatted( col, buf );
}
void SourceView::RenderLine( const Tokenizer::Line& line, int lineNum, const AddrStat& ipcnt, const AddrStatData& as, Worker* worker, const View* view )
{
const auto scale = GetScale();
@ -4174,27 +4182,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR
{
const float rate = float( branchRel ) / branchRelMax;
uint32_t col = GetGoodnessColor( 1.f - rate * 3.f );
if( rate >= 1.f )
{
TextColoredUnformatted( col, " 100% " );
}
else
{
char buf[16];
if( rate >= 0.1f )
{
const auto end = PrintFloat( buf, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
else
{
*buf = ' ';
const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
memcpy( buf+4, "% ", 3 );
TextColoredUnformatted( col, buf );
}
PrintPercentageUnformattedFixedWidth( rate * 100.f, col );
if( ImGui::IsItemHovered() )
{
UnsetFont();
@ -4218,25 +4206,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR
{
const float rate = float( cacheRel ) / cacheRelMax;
uint32_t col = GetGoodnessColor( 1.f - rate * 3.f );
if( rate >= 1.f )
{
TextColoredUnformatted( col, " 100%" );
}
else
{
char buf[16];
const auto end = PrintFloat( buf, buf+16, rate * 100, 1 );
memcpy( end, "%", 2 );
if( end - buf == 4 )
{
TextColoredUnformatted( col, buf );
}
else
{
ImGui::SameLine( 0, ts.x );
TextColoredUnformatted( col, buf );
}
}
PrintPercentageUnformattedFixedWidth( rate * 100.f, col );
if( ImGui::IsItemHovered() )
{
UnsetFont();
@ -4263,31 +4233,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR
const bool unreliable = branchRetired < 10;
const float rate = float( branchMiss ) / branchRetired;
uint32_t col = unreliable ? 0x44FFFFFF : GetGoodnessColor( 1.f - rate * 3.f );
if( branchMiss == 0 )
{
TextColoredUnformatted( col, " 0% " );
}
else if( rate >= 1.f )
{
TextColoredUnformatted( col, " 100% " );
}
else
{
char buf[16];
if( rate >= 0.1f )
{
const auto end = PrintFloat( buf, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
else
{
*buf = ' ';
const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
memcpy( buf+4, "% ", 3 );
TextColoredUnformatted( col, buf );
}
PrintPercentageUnformattedFixedWidth( rate * 100.f, col );
if( ImGui::IsItemHovered() )
{
UnsetFont();
@ -4313,31 +4259,7 @@ void SourceView::RenderHwLinePart( size_t cycles, size_t retired, size_t branchR
const bool unreliable = cacheRef < 10;
const float rate = float( cacheMiss ) / cacheRef;
uint32_t col = unreliable ? 0x44FFFFFF : GetGoodnessColor( 1.f - rate * 3.f );
if( cacheMiss == 0 )
{
TextColoredUnformatted( col, " 0%" );
}
else if( rate >= 1.f )
{
TextColoredUnformatted( col, " 100%" );
}
else
{
char buf[16];
if( rate >= 0.1f )
{
const auto end = PrintFloat( buf, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
else
{
*buf = ' ';
const auto end = PrintFloat( buf+1, buf+16, rate * 100, 1 );
assert( end == buf+4 );
}
memcpy( buf+4, "%", 2 );
TextColoredUnformatted( col, buf );
}
PrintPercentageUnformattedFixedWidth( rate * 100.f, col );
if( ImGui::IsItemHovered() )
{
UnsetFont();