윈도 우즈 에서 밀리초 까지 정확 한 시계 가 직면 한 문제 와 해결 방법 을 실현 하 다
8777 단어 windows
해결 방법 은 GetSystemTime 을 baseline 으로 사용 한 다음 windows 가 제공 하 는 고밀도 타이머 Query PerformanceCounter (자바 에 해당 하 는 함 수 는 System. nanoTime () 로 시간 을 계산 하고 정확 한 시 계 는 baseline + 타이머 시간 입 니 다.
질문 2: Query PerformanceCounter / Query PerformanceFrequency 의 질문
이 문 제 는 주로 windows Query PerformanceCounter 와 의 실현 에 달 려 있다. 초기의 실현 은 the CPU - level timestamp - counter (TSC) 를 사용 하 는 것 이 었 다. tick count 는 서로 다른 핵 에서 의 값 차이 가 비교적 크기 때문에 이 타 이 머 를 사용 하여 계산 한 값 은 전혀 예측 할 수 없 었 다. 초기 에 비교적 간단 한 해결 방법 은 특정한 스 레 드 에서 만 타 이 머 를 사용 하 는 것 이 었 다.그리고 이 스 레 드 를 핵 에 묶 습 니 다. (그러나 자바 의 스 레 드 는 cpu affinity 를 설정 할 수 없습니다)
windows xp sp2 와 windows server 2003 sp2 및 이후 시스템 에 서 는 Query Performance Counter 를 사용 하여 power management timer PMTimer 를 선택 할 수 있 습 니 다. boot. ini 에 / usepmtimer 옵션 을 추가 하여 Query Performance Counter 의 실현 방식 을 설정 할 수 있 습 니 다. PMTimer 는 메인보드 의 타 이 머 를 사용 하기 때문에 다 핵 동기 화 문제 가 없습니다.
요약: 1. Query PerformanceFrequency 의 반환 값 (매개 변수) 을 검사 합 니 다.
반환 값 = 3, 579, 545 는 현재 시스템 에서 PMTimer 를 사용 합 니 다. --> step 3
반환 값 = CPU 주파수, 시스템 사용 TSC --> step 2
2. 운영 체제 가 windows xp sp2 / windows server 2003 sp2 or later 라면 c: \ boot. ini 에 인자 / usepmtimer 를 추가 하고 시스템 을 다시 시작 합 니 다.
3. GetSystem Time + QueryPerformanceCounter 를 사용 하여 정확 한 시계 참 조 를 실현 합 니 다.
---------------------------------------------------------------------------------
http://msdn.microsoft.com/zh-cn/windows/hardware/gg463347
http://support.microsoft.com/kb/833721
http://support.microsoft.com/kb/895980
http://blogs.oracle.com/dholmes/entry/inside_the_hotspot_vm_clocks
Windows use of clocks and timers varies considerably from platform to platform and is plagued by problems - again this isn't necessarily Window's fault, just as it wasn't the VM's fault: the hardware support for clocks/timers is actually not very good - the references at the end lead you to more information on the timing hardware available. The following relates to the "NT" family (win 2k, XP, 2003) of Windows.
There are a number of different "clock" API's available in Windows. Those used by Hotspot are as follows:
The timer related API's for doing timed-waits all use the waitForMultipleObjects API as previously mentioned. This API only accepts timeout values in milliseconds and its ability to recognize the passage of time is based on the timer interrupt programmed through the hardware.
Typically a Windows machine has a default 10ms timer interrupt period, but some systems have a 15ms period. This timer interrupt period may be modified by application programs using the timeBeginPeriod/timeEndPeriod API's. The period is still limited to milliseconds and there is no guarantee that a requested period will be supported. However, usually you can request a 1ms timer interrupt period (though its accuracy has been questioned in some reports). The hotspot VM in fact uses this 1ms period to allow for higher resolution Thread.sleep calls than would otherwise be possible. The sample Sleeper.java will cause this higher interrupt rate to be used, thus allowing experimentation with a 1ms versus 10ms period. It simply calls Thread.sleep(Integer.MAX_VALUE) which (because it is not a multiple of 10ms) causes the VM to switch to a 1ms period for the duration of the sleep - which in this case is "forever" and you'll have to ctrl-C the "java Sleeper" execution.
public class Sleeper { public static void main(String[] args) throws Throwable { Thread.sleep(Integer.MAX_VALUE); } }
You can see what interrupt period is being used in Windows by running the perfmon tool. After you bring it up you'll need to add a new item to watch (click the + icon above the graph - even if it appears grayed/disabled). Select the interrupts/sec items and add it. Then right click on interrupts/sec under the graph and edit its properties. On the "data" tab, change the "scale" to 1 and on the graph tab, the vertical max to be 1000. Let the system settle for a few seconds and you should see the graph drawing a steady line. If you have a 10ms interrupt then it will be 100, for 1ms it will be 1000, for 15ms it will be 66.6, etc. Note: on a multiprocessor system show the interrupts/sec for each processor individually, not the total - one processor will be fielding the timer interrupts.
Note that any application can change the timer interrupt and that it affects the whole system. Windows only allows the period to be shortened, thus ensuring that the shortest requested period by all applications is the one that is used. If a process doesn't reset the period then Windows takes care of it when the process terminates. The reason why the VM doesn't just arbitrarily change the interrupt rate when it starts - it could do this - is that there is a potential performance impact to everything on the system due to the 10x increase in interrupts. However other applications do change it, typically multi-media viewers/players. Be aware that a browser running the JVM as a plug-in can also cause this change in interrupt rate if there is an applet running that uses the Thread.sleep method in a similar way to Sleeper.
Further note, that after Windows suspends or hibernates, the timer interrupt is restored to the default, even if an application using a higher interrupt rate was running at the time of suspension/hibernation.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
제한된 크기의 디렉토리를 만드는 방법오늘 저는 장치에 공간이 없을 때 백업 중에 응용 프로그램이 어떻게 작동하는지 테스트(및 수정)하는 작업이 있습니다. 결과적으로 "남은 공간 없음"오류로 백업이 실패하면 새 파일이 없어야 합니다. 지금까지 문제를 재...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.