Sunday, 15 April 2012

c++ - Accuracy (not precision) of std::chrono::high_resolution_clock and screen refresh rate -



c++ - Accuracy (not precision) of std::chrono::high_resolution_clock and screen refresh rate -

i'm using visual studio 2012 , know accuracy of high_resolution_clock.

basically i'm writing code display sound , images, need them synchronised, , images must tear free. i'm using directx give tear free images , timing screen refreshes using high_resolution_clock. display claims 60 fps, however, timing high_resolution_clock gives refresh rate of 60.035 fps, averaged on 10000 screen refreshes. depending upon right sound end out 0.5 ms after second, around 2 s after hour. expect clock more accurate - more 1 s drift on year, not hour.

has ever looked @ kind of stuff before. should expect sound card clock different again?

edit here timing code. while loop runs in rendering thread. m_renderdata , array of structs containing info needed rendering scene, has 1 element per screen. tests i'm running on 1 screen has 1 elements

while(!testdestroy()) { for(size_t i=0; i<m_renderdata.size(); ++i) { //work out in vsync cycle , increment render cycle //as needed until need 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 missing vsync 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 time render //record time , increment number of renders have been performed m_renderdata[i].durations.push_back(std::chrono::high_resolution_clock::now()); ++m_renderdata[i].nrenders; //we calculate fps using 10001 times - i.e. interval of 10000 frames size_t fpsupdateperiod=10001; if(m_renderdata[i].nrenders<fpsupdateperiod) { //if don't have plenty times display message m_renderdata[i].fpsstring = "fps: calculating"; } else { //we have plenty timing info, calculate 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 buffer screen rendertobackbuffer(i); //display buffer if(!testdestroy()) m_renderdata[i].deviced3d9->present(null, null, null, null); //make sure render right buffer next time m_renderdata[i].buffertorender--; //update render cycle m_renderdata[i].renderstage=invblankrenderingcomplete; } } }

unfortunately, in vs 2012 , 2013 chrono::high_resolution_clock not using rdtsc. fixed future version of vs. see vs connect. in meantime, utilize qpc instead.

c++ time directx monitor

No comments:

Post a Comment