2012-03-01 7 views
8

OS를 예상보다 더 오래 잔다. 나는 100 번 반복하여 총 수면 시간이 100 대신에 1500ms였습니다.WinAPI를 수면() 함수를 호출

이 일반적인 행동입니까, 아니면 내 MOBO, CPU, Windows 설치와 관련해서 뭔가 잘못된 점에 대해 협의해야합니까?

편집 : 가능한 경우이 코드를 실행하고 잠자기 시간이 얼마나 남았는지 게시 할 수 있습니다. 나는 내 친구가 이걸 돌릴 수있게 해줬고 실제로 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 : 어떤 사람들은이 1ms를 얻고있는 이유는 다른 프로그램이 1ms에 시스템 전체의 타이머 해상도를 설정하는 실행되는 것 같다. 기본적으로 이것은 Windows 7에서 15.6ms가되어야합니다.

+0

에서 찾을 수있다 (하드웨어/os, 그 시간에 프로세서의 부하 등) 나는 당신이 사람들에게 그 코드를 실행하도록 요청함으로써 성취하고자하는 것이 무엇인지 확신하지 못한다. 루프가 반복 될 때마다 루프가 실행될 때마다 다른 시간을 출력하는 것이 가능할 것입니다. – obmarg

+0

Sleep()은 Windows에서 하드웨어와 관련이 없다고 생각합니다. timeBeginPeriod()를 사용하는 프로그램을 실행하지 않으면 결과는 15-16ms가되어야합니다. 예 : Windows Media Player에서 10ms로 설정하고 BSPlayer에서 1ms로 설정합니다. 또한 일부 브라우저에서는이를 조정한다고합니다. – NFRCR

+0

아마 직접 연결되어 있지는 않지만 간접적 인 링크가있을 수 있습니다. 매우 낮은 전력이 공급되는 컴퓨터에서 창문을 달리는 경우로드가 올라가고 수면 복귀가 오기도 전에 시간이 걸릴 수 있습니다. – obmarg

답변

7

이 일반적인 행동이이

입니다.

창 스레드 스케줄러는 시간 퀀텀에서 작동합니다 (정확한 길이는 Windows 버전 및 에디션을 포함한 다양한 요소에 따라 다릅니다). 효과적으로 0이 아닌 지연은 완전한 퀀텀으로 반올림됩니다.

+0

@MatteoItalia 실행할 수있는 것이없는 경우 (이 우선 순위 또는 더 높은 우선 순위에서) 0 수면이 즉시 반환됩니다. 전혀 차단되지 않을 수 있습니다. 0이 아닌 값을 사용하면 이해할 수 있도록 항상 차단이있을 것입니다. – Richard

+0

수정, 삭제 중입니다. –

0

(디버그 또는 구축? 해제)

을 어떻게 지연을 측정하는? 정확한 방법을 사용하고 있습니까? (queryperformancecounter)

정확한 타이밍을 위해 Windows OS에 의존해야한다고 생각하지 않습니다. 그것은 실시간 운영체제가 아니며, 프로세스에서 시간을 훔칠 외부 "힘"이있을 것입니다.

11

절전 모드로 전환하면 스레드가 지정된 제한 시간보다 오래 동안 절전 모드가 될 수 있습니다. 절전 모드로 전환하면 스레드가 최소한 일정 시간 동안 절전 모드로 유지됩니다. documentation에서

: 슬립 간격이 경과

후, 스레드를 실행할 준비가되어 있습니다. 0 밀리 초를 지정하면 스레드는 나머지 시간 조각을 포기하지만 준비 상태를 유지합니다. 준비 스레드가 즉시 실행되는 것은 아닙니다. 결과적으로 스레드는 절전 간격이 경과 한 후 얼마 지나지 않아야 실행될 수 있습니다. 자세한 내용은 Scheduling Priorities을 참조하십시오.

1

대부분의 시계 해상도가 약 10 ~ 15 밀리과 마찬가지로이 꽤 정상적인 동작입니다. 따라서 클럭 해상도 (해당 경우, 1)보다 작은 값으로 호출하면 적어도 한 클럭주기 동안 기다려야하기 때문에 원하는 시간보다 오래 자게됩니다.

일반적으로 이러한 문제로 인해 정밀도가 필요한 사항에는 절전 모드를 사용하지 마십시오.

2

Windows에서의 타이밍 관련 최고의 기사는 herehere입니다. 유용한 부분은 멀티미디어 타이머 해상도 (예 : timeBeginPeriod(1) 1ms)를 변경하면 일반적으로 스케줄러에 영향을주기 때문에 Sleep 명령에도 영향을 미칩니다. 비 실시간 OS에서는 1ms의 정확도를 달성 할 수 없습니다.

1

동작이 정상입니다. 기본 하드웨어, OS 버전, 심지어 소프트웨어 실행은 sleep() 함수와 관련하여 OS의 습관에 영향을 미치고 있습니다.

시스템 인터럽트 기간보다 작은 dwMilliseconds로 sleep이 호출되면 다음 인터럽트에서 호출이 반환됩니다. 이런 식으로 실제 지연은 (인터럽트 기간과 관련하여) 슬립이 호출 된 시간에 따라 달라집니다.

멀티미디어 타이머 인터페이스를 사용하여 sleep (1)이 필요할 때 인터럽트 빈도를 하드웨어가 지원하는 최대 값으로 높이는 것이 좋습니다. 슬립 쉽게 다양한 인자에 따라 서로 다른 시간이 걸릴 수 있기 때문에

슬립() 함수 때 Waitable 타이머 기능, 타이머 해상도 및 멀티미디어 타이머 설정에 대한 상세한 개관이 Windows Timestamp Project