查询性能计数器睡眠问题

时间:2014-07-14 23:08:33

标签: c++ winapi

您好我试图以一定的速率遍历一段代码。在这个例子中,我的目标是每秒执行120次代码块。我已经实现了这个,我使用计数器来查看每个循环完成的循环次数,每秒得到220次。这是我的代码... USERUPDATE是一个1 / 120.0f的常量,timeInterval是USERUPDATE,以纳秒为单位,我将所有时间值转换为纳秒,用于sleep_for(nano())......

LARGE_INTEGER grabCpuTicks;
unsigned long long globalInterval;
unsigned long long timeInterval = (unsigned long long)(USERUPDATE*1000000000.0f);

LARGE_INTEGER cyclePerSecond;
LARGE_INTEGER ElapsedNanoSeconds;
LARGE_INTEGER PreviousNanoSeconds;

QueryPerformanceFrequency( &cyclePerSecond);

QueryPerformanceCounter(&grabCpuTicks);
PreviousNanoSeconds.QuadPart = grabCpuTicks.QuadPart;

int counter = 0;
loopTimer->setTime();


while(true)
{


    //Keyboard user input updates
    bool *keys = input->GetKeys();
    bool *mouse = input->GetClicks();
    Vector drawPos;
    double fireStrength;
    Vector temp = GetAngPos();


    if(!mouse[0] && fire && currObj != NULL)
    {
        fire = !fire;
        fireTime->setTime();
    }
    else if(mouse[0] && !fire && currObj != NULL)
    {
        Vector pos(player->GetLinPos().getx(), player->GetLinPos().gety() - 3.0f*USERHEIGHT/4.0f, player->GetLinPos().getz());

        fireStrength = fireTime->getTime()*800.0f;
        if(fireStrength > MAXSPEED)
        {
            fireStrength = MAXSPEED;
        }
        currObj = items->getNext(currObj);
        currObj->mesh->SetTrajectory(pos,GetAngPos(),fireStrength, NULL);
        fire = !fire;
    }


    //If second has passed
    if(loopTimer->getTime() >= 1.0f)
    {
        cout << "Number of loops per second: " << counter << endl;
        counter = 0;
        loopTimer->setTime();
    }
    counter++;



    QueryPerformanceCounter(&grabCpuTicks);
    ElapsedNanoSeconds.QuadPart = grabCpuTicks.QuadPart - PreviousNanoSeconds.QuadPart;

    //reset tick count for next timing interval
    PreviousNanoSeconds.QuadPart = grabCpuTicks.QuadPart;

    //convert to nano seconds
    ElapsedNanoSeconds.QuadPart *= 1000000000;
    //Divide by CPU Cycles per second
    ElapsedNanoSeconds.QuadPart /= (cyclePerSecond.QuadPart);

    globalInterval = ElapsedNanoSeconds.QuadPart;

    //Global interval compensates for time computing so the timestep
    //is actually in whole correct including computation time and sleep time
    if(timeInterval > (globalInterval))
    {
        std::this_thread::sleep_for(std::chrono::nanoseconds(timeInterval - globalInterval));
    }



}

1 个答案:

答案 0 :(得分:0)

Windows Sleep功能的分辨率非常低。你需要一个高分辨率计时器。通常的解决方案是使用multimedia timer

如果分辨率不够高,那么您需要一个繁忙的循环并使用性能计数器进行计时。