Audio latency measuring sample for Windows
This code sample demonstrates how to measure minimum, maximum and average execution times of a routine or a portion of code with high resolution time stamps in Visual C++. The values obtained are calculated in microseconds.
// Code to measure minimum, maximum and average execution times of a routine in microseconds
// NOTE: build a RELEASE version of this code to get useful results
// The data that we are interested in:
float minExecutionTime,maxExecutionTime,averageExecutionTime;
// Other vars
float currentExecutionTime,totalExecutionTime,freqFactor;
ULONG executionCount;
BOOL doMeasure;
void Initialization(void) ;
void UpdateStats(LONGLONG elapsed);
// Run this code only once at initialization
void Initialization(void)
{
LARGE_INTEGER perfFrequency;
currentExecutionTime=0;
executionCount=0;
minExecutionTime=0;
maxExecutionTime=0;
averageExecutionTime=0;
totalExecutionTime=0;
doMeasure=FALSE;
// Get performance frequency in counts per second
if (QueryPerformanceFrequency(&perfFrequency)!=TRUE)
{
// Something went wrong, measuring will not work
freqFactor=0;
}
else
{
// The freqFactor is the amount of microseconds of a single performance count
freqFactor=(float)1000000/perfFrequency.QuadPart;
doMeasure=TRUE;
}
}
void UpdateStats(LONGLONG elapsed)
{
// Calculated elapsed execution time in microseconds
currentExecutionTime=elapsed*freqFactor;
// Update minimum execution time
if (currentExecutionTime < minExecutionTime || minExecutionTime==0)
minExecutionTime=currentExecutionTime;
// Update maximum execution time
if (currentExecutionTime > maxExecutionTime)
maxExecutionTime=currentExecutionTime;
// increase number of successful measurings
executionCount++;
// Update total and average
totalExecutionTime+=currentExecutionTime;
averageExecutionTime=totalExecutionTime/executionCount;
}
// Your code to be measured, this could be your audio process function
// Make sure that Initialization() has been called once before
void MyCodeToBeMeasured(void)
{
LARGE_INTEGER start={0,0},end={0,0};
if (doMeasure==TRUE)
{
// Set this code to run only at first CPU
// If we are running on another CPU then we get rescheduled immediately
SetThreadAffinityMask (GetCurrentThread(),1);
// Get the performance time stamp at the beginning of your code
QueryPerformanceCounter(&start);
}
// ...
// now run the code you wish to be measured
// ...
// Get the performance time stamp at the end of your code
// and update our data
if (doMeasure==TRUE)
{
QueryPerformanceCounter(&end);
if (start.QuadPart > 0 && end.QuadPart > 0)
{
UpdateStats(end.QuadPart-start.QuadPart);
}
// minExecutionTime, maxExecutionTime and averageExecutionTime are now filled
// with useful data representing execution times in microseconds
}
}