.NETタイマーが15ミリ秒の解像度に制限されているのはなぜですか?



Why Are Net Timers Limited 15 Ms Resolution



解決:

おそらく、ここにリンクされているドキュメントはそれを少し説明しています。ちょっと乾燥しているので、すぐに閲覧しただけです:)

イントロを引用する:



システムタイマーの解像度によって、Windowsが2つの主要なアクションを実行する頻度が決まります。

  • フルティックが経過した場合は、タイマーティックカウントを更新します。
  • スケジュールされたタイマーオブジェクトの有効期限が切れているかどうかを確認します。

タイマーティックは、Windowsが時刻とスレッドクォンタム時間を追跡するために使用する経過時間の概念です。デフォルトでは、クロック割り込みとタイマーティックは同じですが、Windowsまたはアプリケーションでクロック割り込み期間を変更できます。



Windows 7のデフォルトのタイマー解像度は15.6ミリ秒(ms)です。一部のアプリケーションでは、これを1ミリ秒に短縮します。これにより、モバイルシステムでのバッテリーの実行時間が最大25%短縮されます。

原産地:タイマー、タイマー解決、および効率的なコードの開発(docx)。


タイマーの分解能は、システムのハートビートによって与えられます。これは通常、デフォルトで64ビート/秒(15.625ミリ秒)になります。ただし、これらのシステム全体の設定を変更して、新しいプラットフォームでは1ミリ秒または0.5ミリ秒までのタイマー解像度を実現する方法があります。



1.マルチメディアタイマーインターフェイスを使用して1ミリ秒の解像度を実現します。

マルチメディアタイマーインターフェイスは、最大1ミリ秒の解像度を提供できます。詳細については、マルチメディアタイマー(MSDN)、タイマー解像度の取得と設定(MSDN)、およびこの回答を参照してください。timeBeginPeriod。注:完了したら、timeEndPeriodを呼び出して、デフォルトのタイマー解像度に戻すことを忘れないでください。

実行する方法:

#define TARGET_RESOLUTION 1 // 1ミリ秒のターゲット解像度TIMECAPStc; UINT wTimerRes; if(timeGetDevCaps(&tc、sizeof(TIMECAPS))!= TIMERR_NOERROR){//エラー;アプリケーションを続行できません。 } wTimerRes = min(max(tc.wPeriodMin、TARGET_RESOLUTION)、tc.wPeriodMax); timeBeginPeriod(wTimerRes); //ここであなたの仕事を約で行います。 1ミリ秒のタイマー解決timeEndPeriod(wTimerRes);

注:この手順は他のプロセスでも使用でき、取得した解像度はシステム全体に適用されます。プロセスによって要求される最高の解決策がアクティブになり、結果に注意してください。

2. 0.5ミリ秒の解像度に移行:

君は 0.5ミリ秒を取得する可能性があります 隠しAPIによる解決NtSetTimerResolution()。 NtSetTimerResolutionは、ネイティブのWindowsNTライブラリNTDLL.DLLによってエクスポートされます。タイマーの解像度を0.5msに設定する方法を参照してください。 MSDNで。それにもかかわらず、真の達成可能な解決策は、基盤となるハードウェアによって決定されます。最新のハードウェアは0.5ミリ秒の解像度をサポートしています。詳細については、Inside WindowsNT高解像度タイマーを参照してください。サポートされている解像度は、NtQueryTimerResolution()を呼び出すことで取得できます。

実行する方法:

#define STATUS_SUCCESS 0 #define STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000245 // ntdll.dllからNtSetTimerResolutionをロードした後://要求された解像度を100 ns単位で:ULONG DesiredResolution = 5000; //注:サポートされている解像度は、NtQueryTimerResolution()の呼び出しによって取得できます。ULONGCurrentResolution= 0; // 1.より高い解像度を要求する//注:この呼び出しはtimeBeginPeriodに似ています。 //ただし、解像度を100ns単位で指定します。 if(NtSetTimerResolution(DesiredResolution、TRUE、&CurrentResolution)!= STATUS_SUCCESS){//呼び出しが失敗しました} printf( 'CurrentResolution [100 ns units]:%d  n'、CurrentResolution); //これは最新のプラットフォーム(0.5ms!)で5000を表示します//ここで0.5msのタイマー解像度で作業を行います// 2。要求された解像度を解放します//注:この呼び出しはtimeEndPeriodスイッチ(NtSetTimerResolution(DesiredResolution、 FALSE、&CurrentResolution){case STATUS_SUCCESS:printf( '現在の解像度が%d [100ns単位]に戻りました n'、CurrentResolution); break; case STATUS_TIMER_RESOLUTION_NOT_SET:printf( '要求された解像度が設定されていません n'); //解像度はFALSEによってのみ前の値に戻ることができます//現在の解像度がこのアプリケーションによって設定された場合break;デフォルト://呼び出しは失敗しました}

注:NtSetTImerResolutionの機能は、基本的に関数にマップされますtimeBeginPeriod bool値を使用したtimeEndPeriodセット(スキームとそのすべての影響の詳細については、Windows NT高解像度タイマーの内部を参照してください)。ただし、マルチメディアスイートでは粒度がミリ秒に制限されており、NtSetTimerResolutionではミリ秒未満の値を設定できます。