我正在使用visual studio 2012,并想知道high_resolution_clock的准确性。std :: chrono :: high_resolution_clock和屏幕刷新率的准确性(不精确)
基本上我正在写一些代码来显示声音和图像,但我需要它们很好地同步,并且图像必须是无撕裂的。我使用directX提供无泪图像,并使用high_resolution_clock在计时屏幕刷新。显示器声称是60 fps,但是,high_resolution_clock的时序提供了60.035 fps的刷新率,平均超过10000次屏幕刷新。取决于哪一个是正确的,我的音频会在一秒钟后的0.5毫秒内结束,即一小时后约2秒。我希望任何时钟都比这更准确 - 更像1秒钟漂移一年,而不是一个小时。
有没有人曾经看过这种东西。我应该期望我的声卡时钟再次变得不同吗?
编辑 这是我的计时代码。这个while循环在我的渲染线程中运行。 m_renderData是包含渲染场景所需数据的结构数组,每个屏幕都有一个元素。为了测试我只在一个屏幕上运行,所以它只有一个chrono::high_resolution_clock
没有使用RDTSC元素
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;
}
}
}
你赔偿了时钟漂移吗? (即确保你设置你的截止日期相对于最后期限,而不是当前时间) – Erbureth
另请参阅:http://stackoverflow.com/questions/8386128/how-to-get-the-precision-of-high-resolution-时钟和http://stackoverflow.com/questions/16299029/resolution-of-stdchronohigh-resolution-clock-doesnt-correspond-to-measureme(第二个问题的接受答案是关于MSVS2012) – Ilya
大多数SO和其他帖子意味着C++ 11 chrono :: high_resolution_clock正在使用RDTSC/RDTSCP指令(未确认)。 MS关于高分辨率定时器的指导是改用QPC API(例如http://msdn.microsoft.com/en-us/library/windows/desktop/dn553408%28v=vs.85%29.aspx) – holtavolt