Я использую Visual Studio 2012 и хотел бы узнать о точности high_resolution_clock.
В основном я пишу некоторый код для отображения звука и изображений, но мне нужно, чтобы они были очень хорошо синхронизированы, и изображения должны быть без разрывов. Я использую DirectX для создания изображений без слез, и я обновляю экран времени, используя high_resolution_clock. Дисплей утверждает, что он составляет 60 кадров в секунду, однако синхронизация с high_resolution_clock дает частоту обновления 60,035 кадров в секунду, в среднем более 10000 обновлений экрана. В зависимости от того, что правильно, мой звук закончится через 0,5 мс через секунду, что составляет около 2 с через час. Я ожидал бы, что любые часы будут точнее, чем дрейф в 1 с в течение года, а не часа.
Кто-нибудь когда-либо смотрел на подобные вещи раньше? Стоит ли ожидать, что часы моей звуковой карты снова будут другими?
редактировать
Вот мой временной код. Этот цикл while выполняется в моем потоке рендеринга. m_renderData — это массив структур, содержащий данные, необходимые для рендеринга моей сцены, он имеет один элемент на экран. Для тестов я работаю только на одном экране, поэтому он имеет только один элемент
while(!TestDestroy())
{
for(size_t i=0; i<m_renderData.size(); ++i)
{
//work out where in the vsync cycle we are and increment the render cycle
//as needed until we need to actually render
D3DRASTER_STATUS rStatus;
m_renderData[i].deviceD3D9->GetRasterStatus(0, &rStatus);
if(m_renderData[i].renderStage==inVBlankRenderingComplete)
{
if(!rStatus.InVBlank)
m_renderData[i].renderStage=notInVBlank;
}
else if(m_renderData[i].renderStage==notInVBlank)
{
if(rStatus.InVBlank)
m_renderData[i].renderStage=inVBlankReadyToRender;
}
//check for missing the vsync for rendering
bool timeOut=false;
if(m_renderData[i].durations.size()>0)
{
double timeSinceLastRender=std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now()-m_renderData[i].durations.back()).count();
if (timeSinceLastRender>expectedUpdatePeriod*1.2)
timeOut=true;
}
if(m_renderData[i].renderStage==inVBlankReadyToRender || timeOut)
{
//We have reached the time to render
//record the time and increment the number of renders that have been performed
m_renderData[i].durations.push_back(std::chrono::high_resolution_clock::now());
++m_renderData[i].nRenders;
//we calculate the fps using 10001 times - i.e. an interval of 10000 frames
size_t fpsUpdatePeriod=10001;
if(m_renderData[i].nRenders<fpsUpdatePeriod)
{
//if we don't have enough times then display a message
m_renderData[i].fpsString = "FPS: Calculating";
}
else
{
//we have enough timing info, calculate the fps
double meanFrameTime = std::chrono::duration_cast<std::chrono::microseconds>(m_renderData[i].durations.back()-*(m_renderData[i].durations.end()-fpsUpdatePeriod)).count()/double(fpsUpdatePeriod-1);
double fps = 1000000.0/meanFrameTime;
saveFps(fps);
}
//render to the back buffer for this screen
renderToBackBuffer(i);
//display the back buffer
if(!TestDestroy())
m_renderData[i].deviceD3D9->Present(NULL, NULL, NULL, NULL);
//make sure we render to the correct back buffer next time
m_renderData[i].bufferToRender--;
//update the render cycle
m_renderData[i].renderStage=inVBlankRenderingComplete;
}
}
}
К сожалению, в VS 2012 и 2013 годах chrono::high_resolution_clock
не использует RDTSC. Это исправлено для будущей версии VS. Увидеть VS Connect. А пока используйте QPC.