c ++ - WinAPI Sleep () funktionsopkald sover længere end forventet

Indlæg af Hanne Mølgaard Plasc

Problem



OS: Windows 7


Når du kalder WinAPI Sleep () -funktionen som Sleep (1), sover tråden faktisk i 15ms. Jeg gjorde det 100 gange i en løkke og den samlede søvntid var 1500ms i stedet for 100.


Er denne almindelige opførsel, eller skal jeg blive koncert om noget, der er galt med min MOBO, CPU, Windows-installation?


EDIT: Hvis det er muligt, kan du køre denne kode og angive, hvor længe søvntiden var. Jeg lod en ven af ​​mig køre dette, og han havde faktisk det hele på 1ms.


#include <iostream>
#include <ctime>
#include <Windows.h>

void test(void)
{
    std::cout << "Testing 1ms sleep." << std::endl;

    for (unsigned int i = 0; i < 10; i++)
    {
        std::clock\_t startClocks = std::clock();

        Sleep(1);

        std::clock\_t clocksTaken = std::clock() - startClocks;
        std::cout << "Time: " << clocksTaken << "ms." << std::endl;
    }
}

int main(void)
{
    test();

    std::cin.sync();
    std::cin.get();
    return 0;
}


EDIT2: Det ser ud til at årsagen til, at nogle mennesker får 1ms, er, at et andet program kører, der sætter system-wide timeropløsningen til 1ms. Som standard skal dette være 15,6 ms på Windows 7.

Bedste reference



  Er denne almindelige opførsel



Det er.


Vindues trådplanlægger arbejder på et tidskvantum (den nøjagtige længde afhænger af forskellige faktorer, herunder Windows-version og -udgave). Effektivt er enhver forsinkelse uden forsinkelse afrundet op til et komplet kvantum.

Andre referencer 1


Sleep kan få tråden til at sove længere end den angivne timeout, det garanterer kun, at tråden vil sove i mindst den pågældende tid.


Fra dokumentationen: [3]



  Når søvnintervallet er gået, er tråden klar til at køre. Hvis du angiver 0 millisekunder, vil tråden afstå resten af ​​sin tidsskive, men forbliver klar. Bemærk, at en klar tråd ikke garanteres at køre med det samme. Derfor kan tråden ikke løbe, før der går et stykke tid efter, at søvnintervallet er gået. Se Scheduling Priorities for yderligere information. [4]


Andre referencer 2


De bedste artikler jeg har fundet vedrørende timing på Windows er her og her. Den nyttige del er, at når du ændrer multimedie-timeropløsningen (f.eks. TimeBeginPeriod (1) i 1ms), påvirker den også kommandoen Sleep, fordi den påvirker planlæggeren generelt.
Dette siger, at opnå 1ms nøjagtighed er ikke muligt på et ikke-realtime OS. [5] [6] [7]

Andre referencer 3


Du bør kontrollere din maskinens timeropløsning. Se msdn-dokumentationen for Sleep () for detaljer. [8]

Andre referencer 4


Dette er ret normal opførsel, da de fleste uropløsninger er omkring 10-15 ms. Derfor, hvis du kalder det med en værdi, der er mindre end klokopløsningen (i dit tilfælde 1), vil det sandsynligvis skulle vente i det mindste for en klokkecyklus, hvorfor det sover længere end du vil.


Generelt bør du ikke bruge Sleep for ting, der kræver en sådan præcision på grund af disse problemer.

Andre referencer 5


Opførelsen er OK. Underliggende hardware, version af OS og endda kørende software påvirker
OS-vanen med hensyn til sleep () -funktionen.


Hvis en søvn kaldes med dwMilliseconds mindre end systemafbrydelsesperioden, vender opkaldet tilbage ved næste afbrydelse. På denne måde afhænger den faktiske forsinkelse af det tidspunkt, hvor søvn blev kaldt (med hensyn til afbrydelsesperioden).


Det anbefales at bruge multimedie-timer-grænsefladen til at øge afbrydelsesfrekvensen til det maksimale understøttet af hardwaren, når en søvn (1) ønskes.


En detaljeret oversigt over funktionen sleep (), ventende timerfunktioner, timeropløsninger og multimedie timerindstillinger findes i Windows Timestamp Project [9].

Andre referencer 6


(debug eller release build?)


Hvordan måler du forsinkelsen? bruger du en præcis metode? (QueryPerformanceCounter)


Jeg tror ikke, du bør stole på Windows OS for præcis timing, det er ikke et operativsystem i realtid, og der vil være eksterne 'kræfter', der vil stjæle tiden fra din proces.