2018年06月19日 16時00分 ハードウェア

IntelのSkylake-Xプロセッサーで.NETプログラムが50％遅くなるケースが発見される



IntelのSkylake-X世代のXeonプロセッサーで、従来モデルに比べて.NETアプリケーションに大きな遅延が発生することを、Alois Kraus氏がブログで公表しています。



Why Skylake CPUs Are Sometimes 50% Slower – How Intel Has Broken Existing Code – Alois Kraus

https://aloiskraus.wordpress.com/2018/06/16/why-skylakex-cpus-are-sometimes-50-slower-how-intel-has-broken-existing-code/



Kraus氏はSkylake-X世代の「Xeon Gold 6126」を使うマシンで、旧マシンと比較して大幅にパフォーマンスが落ちる場面に遭遇しました。以下の図は、新マシン(黄色)と旧マシン(青)の遅延時間を示したもので、値が少ないほど性能が高いことを示しています。たいていの不具合については、Windowsの問題やBIOSセッティングの問題が原因であることが多いそうですが、この件についてはKraus氏は、チューニングによって解消することができなかったそうです。





Kraus氏が原因を詳細に調べたところ、.NET Frameworkコード内の「pause」命令を通じて遅延が生じていることがわかったとのこと。





pause命令でCPUが一時的に停止するときの時間を数値化すると、Skylake-X世代のXeonは旧世代のXeon(E5 1620)に比べて10倍も長いことがわかりました。10倍の遅延についてKraus氏は「バグのように思えた」と述べています。





pause命令についてネット検索したKraus氏は、以下のIntelのマニュアルに関連する記載を発見しました。



Intel 64 and IA-32 Architectures Optimization Reference Manual

https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf



この記載によると、Intelはpause命令での従来の10サイクルから140サイクルへと延びることを明らかにしており、pause命令のレイテンシーが増えたことでパフォーマンス低下が起こり得ることを指摘していました。





なお、従来のCoreプロセッサーの各世代のCPUサイクルは以下の通り。実際の実行時間はこのCPUサイクル数をCPU周波数で割ったもので表されますが、Skylake-Xの遅延が一桁違うことは間違いなさそうです。





Skylake-X世代のCPUを使うマシンでは、.NET上で大量のマルチスレッドアプリケーションを実行すると、処理速度が大幅に低下する可能性があるという問題は、2017年8月時点でXiangyang Guo氏によって指摘されていたとのこと。



Spin wait tuning · Issue #13388 · dotnet/coreclr · GitHub

https://github.com/dotnet/coreclr/issues/13388



この問題は次期.NET Frameworkであるバージョン4.8のPreview版や.NET Core 2.1では解消されていますが、2019年の正式リリースまでは問題が残ることになります。なお、Skylake-X世代のCPUで、この問題は.NET特有の問題というわけではなく、pause命令を使うSpinlockの実装すべてに影響を与えるとKraus氏は指摘しています。





Kraus氏が指摘した問題についてRedditでは、pause命令が速すぎるとMicrosoftとIntel双方が考え、それぞれ対策を施したという不幸が重なり合った結果ではないかとの指摘があります。



Skylake-X CPUs have 140-cycle "pause" latency with negative effects on .NET Spinlocks : hardware

https://www.reddit.com/r/hardware/comments/8s011f/skylakex_cpus_have_140cycle_pause_latency_with/

