Windowsのシステムタむマヌ倧きな倉曎

Windowsスケゞュヌラの動䜜はWindows10 2004で倧幅に倉曎されたしたが、譊告やドキュメントの倉曎はありたせん。これにより、いく぀かのアプリケヌションが砎損する可胜性がありたす。これが起こったのはこれが初めおではありたせんが、この倉化はより深刻です。



぀たり、あるプロセスからtimeBeginPeriodを呌び出すず、他のプロセスぞの圱響は以前よりも少なくなりたすが、その圱響はただ存圚したす。



新しい動䜜は本質的に改善されたものだず思いたすが、それは奇劙であり、文曞化する䟡倀がありたす。正盎なずころ、私はあなたに譊告したす-私は自分の実隓の結果しか持っおいないので、この倉曎の目暙ずいく぀かの副䜜甚に぀いおしか掚枬できたせん。私の調査結果のいずれかが正しくない堎合は、私に知らせおください。



タむマヌの䞭断ずその理由



たず、オペレヌティングシステムの蚭蚈に぀いお少し説明したす。プログラムが眠りに萜ち、埌で目を芚たすこずができるこずが望たしい。実際、これはあたり頻繁に行うべきではありたせん-スレッドは通垞、タむマヌではなくむベントを埅機したす-しかし、必芁な堎合もありたす。したがっお、Windowsにはスリヌプ機胜 ãŒã‚りたす。必芁なスリヌプ時間をミリ秒単䜍で枡すず、プロセスがりェむクアップしたす。



スリヌプ1;



これがどのように実装されおいるかを怜蚎する䟡倀がありたす。理想的には、Sleep1が呌び出されるず、プロセッサはスリヌプ状態になりたす。しかし、プロセッサがスリヌプ状態の堎合、オペレヌティングシステムはどのようにスレッドをりェむクアップしたすか答えはハヌドりェア割り蟌みです。 OSはチップハヌドりェアタむマヌをプログラムしたす。ハヌドりェアタむマヌは、プロセッサをりェむクアップする割り蟌みをトリガヌし、OSはスレッドを開始したす。



WaitForSingleObject関数ずWaitForMultipleObjects関数にもタむムアりト倀があり、これらのタむムアりトは同じメカニズムを䜿甚しお実装されたす。



タむマヌを埅機しおいるスレッドが倚数ある堎合、OSはスレッドごずに個別の時間にハヌドりェアタむマヌをプログラムできたすが、これは通垞、スレッドがランダムな時間にりェむクアップし、プロセッサが正垞にスリヌプしないずいう事実に぀ながりたす。 CPUの電力効率は、スリヌプ時間通垞の時間は8msに倧きく䟝存し、ランダムりェむクはこれに寄䞎したせん。耇数のスレッドがタむマヌの期埅倀を同期たたはプヌルするず、システムの゚ネルギヌ効率が向䞊したす。



りェむクを組み合わせる方法はたくさんありたすが、Windowsの䞻なメカニズムは、䞀定の速床で刻々ず倉化するタむマヌをグロヌバルに䞭断するこずです。スレッドがSleepnを呌び出すず、OSは最初のタむマヌ割り蟌みの盎埌にスレッドが開始するようにスケゞュヌルしたす。぀たり、スレッドは少し遅れおりェむクアップする可胜性がありたすが、WindowsはリアルタむムOSではなく、特定のりェむクアップ時間を保蚌するものではありたせんこの時点ではプロセッサコアがビゞヌである可胜性がありたす。したがっお、少し遅れおりェむクアップするのはごく普通のこずです。



タむマヌ割り蟌みの間隔は、Windowsずハヌドりェアのバヌゞョンによっお異なりたすが、すべおのマシンでデフォルトで15.625ms1000ms / 64になっおいたす。これは、Sleep1を呌び出すずあるランダムな時間に、次のグロヌバルタむマヌ割り蟌みがトリガヌされたずきたたは早すぎる堎合は1回埌、プロセスは将来1.0msから16.625msの間のどこかでりェむクアップされたす。



぀たり、タむマヌ遅延の性質は、プロセッサヌのアクティブ埅機が䜿甚されおいる堎合を陀き、䜿甚しないでください、OSはタむマヌ割り蟌みを䜿甚しお特定の時間にのみスレッドをりェむクアップでき、Windowsは通垞の割り蟌みを䜿甚したす。



䞀郚のプログラムWPF、SQL Server、Quartz、PowerDirector、Chrome、Go Runtime、倚くのゲヌムなどでは、埅ち時間にそれほど倧きなばら぀きはありたせん。幞い、timeBeginPeriod関数で問題を修正できたすこれにより、プログラムはより短い間隔を芁求できたす。間隔を1ミリ秒未満に蚭定できるNtSetTimerResolution関数もありたすが、䜿甚されるこずはめったになく、必芁になるこずもないため、ここでは再床説明したせん。



狂気の数十幎



これはおかしなこずです。timeBeginPeriodはどのプログラムからでも呌び出すこずができ、タむマヌ割り蟌み間隔を倉曎したす。タむマヌ割り蟌みはグロヌバルリ゜ヌスです。



プロセスAがSleep1の呌び出しずルヌプしおいるず想像しおみたしょう。これは間違っおいたすが、そうであり、デフォルトでは、15.625msごず、぀たり1秒間に64回りェむクアップしたす。次に、プロセスBが入り、timeBeginPeriod2を呌び出したす。これにより、タむマヌがより頻繁に起動し、プロセスAが毎秒64回ではなく、毎秒500回りェむクアップしたす。これは狂気ですしかし、これはWindowsが垞に機胜しおきた方法です。



この時点で、プロセスCが衚瀺され、timeBeginPeriod4が呌び出された堎合、それは䜕も倉曎したせん-プロセスAは1秒間に500回りェむクアップし続けたす。このような状況では、ルヌルを蚭定するのは最埌の呌び出しではなく、最小間隔の呌び出しです。



したがっお、実行䞭のプログラムからtimeBeginPeriodを呌び出すず、グロヌバルタむマヌの割り蟌み間隔を蚭定できたす。このプログラムが終了するか、timeEndPeriodを呌び出すず、新しい最小倀が有効になりたす。 1぀のプログラムがtimeBeginPeriod1を呌び出す堎合、これはシステム党䜓のタむマヌ割り蟌み間隔になりたす。 1぀のプログラムがtimeBeginPeriod1を呌び出し、別のプログラムがtimeBeginPeriod4を呌び出す堎合、1ミリ秒のタむマヌ割り蟌み間隔は普遍的な法則になりたす。



ここで説明するように、高いタむマヌ割り蟌みレヌトおよびそれに関連する高いスレッドスケゞュヌリングレヌトは、CPUパワヌを倧幅に浪費する可胜性があるため、これは重芁です。



タむマヌベヌスのスケゞュヌリングが必芁なアプリケヌションの1぀は、Webブラりザヌです。 JavaScript暙準には、数ミリ秒埌にJavaScript関数を呌び出すようにブラりザヌに芁求するsetTimeout関数がありたす。 Chromiumはタむマヌを䜿甚しお、この機胜やその他の機胜を実装したす基本的に、Sleepではなくタむムアりト付きのWaitForSingleObject。倚くの堎合、これにはタむマヌの割り蟌み率を䞊げる必芁がありたす。バッテリヌ寿呜を䜎く保぀ために、Chromiumは最近、バッテリヌ電源でタむマヌ割り蟌みレヌトを125 Hz8ms間隔未満に保぀ように再蚭蚈されたした。



timeGetTime



timeGetTime 関数GetTickCountず混同しないでくださいは、タむマヌ割り蟌みによっお曎新された珟圚の時刻を返したす。プロセッサは、歎史的に正確な時刻を維持するのがあたり埗意ではありたせんでしたFM送信機ずしおの機胜を回避するために、およびその他の理由で、それらのクロックは意図的に振動したす。そのため、CPUは、正確な時刻を維持するために別個のクロックゞェネレヌタに䟝存するこずがよくありたす。これらのチップからの読み取りにはコストがかかるため、Windowsはタむマヌ割り蟌みで曎新された64ビットミリ秒カりンタヌを維持したす。このタむマヌは共有メモリに保存されるため、どのプロセスでも、時蚈に行かなくおも、そこから珟圚の時刻を安䟡に読み取るこずができたす。timeGetTimeはReadInterruptTickを呌び出したす。これは、基本的にこの64ビットカりンタヌを読み取るだけです。ずおも簡単です



カりンタはタむマヌ割り蟌みによっお曎新されるため、それを远跡しおタむマヌ割り蟌み頻床を芋぀けるこずができたす。



文曞化されおいない新しい珟実



Windows 10 2004のリリヌス2020幎4月により、これらのメカニズムの䞀郚がわずかに倉曎されたしたが、非垞に玛らわしい方法です。たず、timeBeginPeriodが機胜しなくなったずいうメッセヌゞがありたした。実際、すべおがはるかに耇雑であるこずが刀明したした。



最初の実隓では、さたざたな結果が埗られたした。timeBeginPeriod2を呌び出しおプログラムを実行するず、clockresは2.0msのタむマヌ間隔を瀺したしたが、Sleep1ルヌプを備えた別のテストプログラムは、以前のバヌゞョンのWindowsの500回ではなく、1秒あたり玄64回起動したした。



科孊実隓



次に、システムの動䜜を研究するためのプログラムをいく぀か䜜成したした。1぀のプログラムchange_interval.cppはルヌプ内にあり、1〜15ミリ秒の間隔でtimeBeginPeriodを呌び出したす。圌女は各間隔を4秒間保持しおから、次の間隔に移動したす。15行のコヌド。簡単。



別のプログラムmeasure_interval.cppは、change_interval.cppが倉曎されたずきにその動䜜がどのように倉化するかを確認するために、いく぀かのテストを実行したす。プログラムは3぀のパラメヌタを監芖したす。



  1. 圌女はOSに、NtQueryTimerResolutionを䜿甚しおいるグロヌバルタむマヌの珟圚の解像床を尋ねたす。

  2. timeGetTime, ,  â€” , .

  3. Sleep(1), . .


@FelixPetriconiはWindows10 1909でテストを実行し、Windows 10 2004でテストを実行したした。ゞッタのない結果は次のずおりです。







これは、timeBeginPeriodがすべおのWindowsバヌゞョンでグロヌバルタむマヌ間隔を蚭定するこずを意味したす。timeGetTimeの結果から、少なくずも1぀のプロセッサコアでこのレヌトで割り蟌みがトリガヌされ、時刻が曎新されおいるず蚀えたす。 1909幎の最初の行の2.0もWindowsXPでは2.0、次にWindows 7/8では1.0でしたが、再び2.0に戻ったようです。



ただし、Windows 10 2004では、スケゞュヌリングの動䜜が倧幅に倉曎されたす。以前は、スリヌプの遅延1timeBeginPeriod1を陀いお、どのプロセスでもタむマヌの割り蟌み間隔ず同じで、次のようなグラフが衚瀺され







たす。Windows10 2004では、timeBeginPeriodず別のプロセスtimeBeginPeriodを呌び出さなかったのスリヌプレむテンシずの関係は奇劙に芋え







たす。グラフの巊偎の正確な圢状は䞍明ですが、それは間違いなく前のものずは反察の方向に進みたす



どうしお



効果



redditずhacker-newsの議論で指摘されおいるように、グロヌバルタむマヌ割り蟌みの利甚可胜な粟床を考えるず、グラフの巊半分は「通垞の」遅延を可胜な限り暡倣しようずしおいる可胜性がありたす。぀たり、6ミリ秒の割り蟌み間隔では、遅延は玄12ミリ秒2サむクル発生し、7ミリ秒の割り蟌み間隔では、玄14ミリ秒2サむクル遅延したす。ただし、実際の遅延を枬定するず、珟実はさらに混乱するこずがわかりたす。タむマヌ割り蟌みが7msに蚭定されおいる堎合、14msのスリヌプ1埅ち時間は、最も䞀般的な結果ではありたせん。







䞀郚のリヌダヌは、システムのランダムノむズを非難する堎合がありたすが、タむマヌ割り蟌みレヌトが9ms以䞊の堎合、ノむズはれロであるため、そうではありたせん。説明かもしれたせん。曎新したコヌドを自分で実行しおみおください。 4msから8msたでのタむマヌ割り蟌み間隔は特に物議を醞しおいるようです。珟圚のコヌドはスケゞュヌリングルヌルの倉曎ずタむマヌの粟床の倉曎によっおランダムに圱響を受けるため、間隔の枬定はおそらくQueryPerformanceCounterを䜿甚しお実行する必芁がありたす。



これはすべお非垞に奇劙で、ロゞックや実装がわかりたせん。これは間違いかもしれたせんが、私はそれを疑っおいたす。この背埌には耇雑な埌方互換性ロゞックがあるず思いたす。ただし、互換性の問題を回避する最も効果的な方法は、できれば事前に倉曎を文曞化するこずです。ここでは、通知なしに線集が行われたす。



これはほずんどのプログラムに圱響したせん。プロセスがより高速なタむマヌ䞭断を必芁ずする堎合は、timeBeginPeriod自䜓を呌び出す必芁がありたす。..。ただし、次の問題が発生する可胜性がありたす。



  • プログラムは、Sleep1ずtimeGetTimeの解像床が同じであるず誀っお想定する可胜性がありたすが、これはもはや圓おはたりたせん。しかし、そのような仮定はありそうもないようです。

  • , .  â€” Windows System Timer Tool TimerResolution 1.2. «» , . , . , , .

  • , , . , . . , , timeBeginPeriod , , .




change_interval.cpp テストプログラムは、誰もより高いタむマヌ割り蟌みレヌトを芁求しない堎合にのみ機胜したす。ChromeずVisualStudioはどちらもこれを行う習慣があるため、むンタヌネットにアクセスしたりメモ垳にコヌディングしたりせずに、ほずんどの実隓を行う必芁がありたした。誰かがEmacsを提案したしたが、この議論に参加するこずは私の力を超えおいたす。



All Articles