Handle GPU timer overflows with heuristics.

This commit is contained in:
Bartosz Taudul 2021-06-09 20:38:06 +02:00
parent 90b51568e9
commit b7b9912b10
No known key found for this signature in database
GPG Key ID: B7FE2008B7575DF3
2 changed files with 27 additions and 7 deletions

View File

@ -617,6 +617,9 @@ struct GpuCtxData
int64_t calibratedGpuTime; int64_t calibratedGpuTime;
int64_t calibratedCpuTime; int64_t calibratedCpuTime;
double calibrationMod; double calibrationMod;
int64_t lastGpuTime;
uint64_t overflow;
uint32_t overflowMul;
StringIdx name; StringIdx name;
unordered_flat_map<uint64_t, GpuCtxThreadData> threadData; unordered_flat_map<uint64_t, GpuCtxThreadData> threadData;
short_ptr<GpuEvent> query[64*1024]; short_ptr<GpuEvent> query[64*1024];

View File

@ -1029,6 +1029,7 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks )
} }
ctx->hasCalibration = false; ctx->hasCalibration = false;
} }
ctx->overflow = 0;
ctx->hasPeriod = ctx->period != 1.f; ctx->hasPeriod = ctx->period != 1.f;
m_data.gpuCnt += ctx->count; m_data.gpuCnt += ctx->count;
uint64_t tdsz; uint64_t tdsz;
@ -5399,6 +5400,9 @@ void Worker::ProcessGpuNewContext( const QueueGpuNewContext& ev )
gpu->calibratedGpuTime = gpuTime; gpu->calibratedGpuTime = gpuTime;
gpu->calibratedCpuTime = cpuTime; gpu->calibratedCpuTime = cpuTime;
gpu->calibrationMod = 1.; gpu->calibrationMod = 1.;
gpu->lastGpuTime = 0;
gpu->overflow = 0;
gpu->overflowMul = 0;
m_data.gpuData.push_back( gpu ); m_data.gpuData.push_back( gpu );
m_gpuCtxMap[ev.context] = gpu; m_gpuCtxMap[ev.context] = gpu;
} }
@ -5571,31 +5575,44 @@ void Worker::ProcessGpuTime( const QueueGpuTime& ev )
auto ctx = m_gpuCtxMap[ev.context]; auto ctx = m_gpuCtxMap[ev.context];
assert( ctx ); assert( ctx );
const int64_t tref = m_refTimeGpu + ev.gpuTime; int64_t tgpu = m_refTimeGpu + ev.gpuTime;
m_refTimeGpu = tref; m_refTimeGpu = tgpu;
const int64_t t = std::max<int64_t>( 0, tref );
if( tgpu < ctx->lastGpuTime )
{
if( ctx->overflow == 0 )
{
ctx->overflow = uint64_t( 1 ) << ( 64 - TracyLzcnt( ctx->lastGpuTime ) );
}
ctx->overflowMul++;
}
ctx->lastGpuTime = tgpu;
if( ctx->overflow != 0 )
{
tgpu += ctx->overflow * ctx->overflowMul;
}
int64_t gpuTime; int64_t gpuTime;
if( !ctx->hasPeriod ) if( !ctx->hasPeriod )
{ {
if( !ctx->hasCalibration ) if( !ctx->hasCalibration )
{ {
gpuTime = t + ctx->timeDiff; gpuTime = tgpu + ctx->timeDiff;
} }
else else
{ {
gpuTime = int64_t( ( t - ctx->calibratedGpuTime ) * ctx->calibrationMod + ctx->calibratedCpuTime ); gpuTime = int64_t( ( tgpu - ctx->calibratedGpuTime ) * ctx->calibrationMod + ctx->calibratedCpuTime );
} }
} }
else else
{ {
if( !ctx->hasCalibration ) if( !ctx->hasCalibration )
{ {
gpuTime = int64_t( double( ctx->period ) * t ) + ctx->timeDiff; // precision loss gpuTime = int64_t( double( ctx->period ) * tgpu ) + ctx->timeDiff; // precision loss
} }
else else
{ {
gpuTime = int64_t( ( double( ctx->period ) * t - ctx->calibratedGpuTime ) * ctx->calibrationMod + ctx->calibratedCpuTime ); gpuTime = int64_t( ( double( ctx->period ) * tgpu - ctx->calibratedGpuTime ) * ctx->calibrationMod + ctx->calibratedCpuTime );
} }
} }