結論:対応しているCPUならば問題なく使える。
先日、JJUG CCC 2025 Fallに参加し、「native のその先へ!System.currentTimeMillis() の実装を見てみよう! / YujiSoftware」のセッションを聴講した。個人的にnativeメソッドの先はあまり考えたことがなく、興味深いテーマだったからだ。currentTimeMillis()の内容を追っていくとJVMのソースに定義が書かれており、openJDK実装ならば、OSによって呼び出すシステムコールが変わる。最終的にはアランブラのRDTSC命令にたどり着くというもの。
RDTSC命令は学生の頃に触れたこともあり(何?19年前?)、やっぱりアレになるのか...。と懐かしく思ったのだが、RDTSC命令は発行時のクロック数を取得するものであり、最近のCPUでは当たり前のようにあるクロック周波数が可変するようなケースではうまく動かないのでは?という疑問が湧き、(実際Athlon64では可変の影響を受けたようで、過去の記事でも言及している。)どうやっているのか気になったので調べてみた。
・CPUクロックに基づく相対時刻の計測
ここの解説が一番わかりやすい。
リンク先の言葉を借りると、CPUの動作クロック毎に積算されるカウンタ(TSC)には以下の3タイプがある
①CPUの動作クロック毎に積算されるTSC
②CPUの動作クロックが変動してもカウンタ積算間隔は一定となる補償機能を追加したConstant TSC
③ACPIのP/C/T状態すべてにおいてカウンタ積算間隔が一定で動作する補償機能を追加したInvariant TSC
で、②③ならクロック数が変動しても使えるということだ。
※out-of-orderの影響を受けないRDTSCP命令があるというのもここで知った。
・タイマーカウンタ その3
TSCがIntelとAMDでどの世代から切り替わったのか調べている記事。
当時自分がAthlon64(K8世代)のTSCは①のTSCで、やはりクロックが可変すると影響を受けていたようだ。その後しばらくしてConstant TSC、Invariant TSC対応のCPUが出ている。2010年代前半には題意の疑問は解消されていたのだな。
と、ここまで調べて同僚と本件を会話したら、Armはどうなのか?と言われた。
調べてみるとArmではRDTSC命令自体が無いようである。アセンブラの世界にまで降りると移植性はなくなるのだな。
おまけ
・マルウェアによるRDTSC命令の利用
マルウェアがどのようにRDTSC命令を使うのか?という記事。クロックサイクル数、時間の経過の観測によってプログラムの存在する宇宙の状態(VMの中かどうか)を観測するような...天文学っぽい感じを受けて興味深い。
