VMware上でubuntu 16.04-4-112から116にしたら遅くなったけど解決した顛末
一言でいうと112から116にするときはVMwareを再起動すること.
試した私の環境はCore i7-7700, Windows 10 Pro, DELL OptiPlex 7050, VMware 12.5.9.
経緯 : ubuntuのkernelのバージョンを112から116にしたらmclのpairing演算に掛かるサイクル数が 1.03Mclkから2.8Mclkと2.7倍以上も遅くなった(同一バイナリ). これは困った.
別のシステムだけどVMwareなしのリアルLinux + Haswellだとその現象は発生しなかった. pairingが遅くなっているマシンでループ内で加算する単純プログラムをテストしたらそれは遅くならなかった.
理由は分からないけどSpectreとMeltdown対策しか原因は思い当たらないのでいろいろオプションを換えて試す. 116起動時にspectre_v2=offを与えると遅くならないことが分かった.
twitterで教えてもらったIBRSまわりをいじる案(/proc/sys/kernel/ibrs_enabled see ubuntu MitigationControls)のは元々dmesgでDefaulting IBRS to disabledと表示されていたので影響はなかった.
まあどこかで対策されるまでしばらくspectre_v2=offで使うしかないのかなと思ったが, Windowsを再起動してテストすると速度低下しない!
いろいろ再起動してテストしても変わらず. これはなんかたまたま遅くなっちゃったけどごめん, 再現しなくなった案件かと思った.
が, 一度や二度の現象じゃなかったのでもう一度遅くならないかもうちょっとがんばる. で, なんとか再現.
どうやら新規にVMwareを起動し112 kernelを起動してから仮想マシン内でrebootして116を再起動すると発現することが分かった. 仮想マシンでshutdownしてVMwareを起動し直して116を動かすと発現しない.
112 kernelじゃなくて116 + spectre_v2=offでも同様. つまり
VMware起動 → 112(or 116 + spectre_v2=off)のkernel起動 → reboot → 116 + spectre_v2=onのkernel起動は速度低下
VMware起動 → 116 + spectre_v2=onのkernel起動は大丈夫
のようだ. VMware内部で仮想マシン起動時になんらかのspectre対策チェックが必要か調べて設定し, その設定は仮想マシンrebootでは引き継がれ, それが対策ありkernelと干渉してるのだろうと推測.
ちなみにこの速度低下が発生している状態で, 上で単純ループでは遅くならなかったと書いたが間接ジャンプやcallを呼ぶタイプだと遅くなった.
// inline版 int main(int argc, char *[]) { long x[2] = { argc, argc }; long y[2] = { argc, argc }; for (int i = argc; i < 1000000000; i++) { x[0] += x[1] + y[0]; x[1] += y[1] + x[0]; } printf("%ld %ld\n", x[0], x[1]); } // call版 void add(long *x, const long *y) { x[0] += x[1] + y[0]; x[1] += y[1] + x[0]; } // mainのループだけ下記に変更 for (int i = argc; i < 1000000000; i++) { add(x, y); } // 間接call版 void (*f)(long *x, const long *y); if (argc) f = add; for (int i = argc; i < 1000000000; i++) { f(x, y); }
最適化がかからないようにg++ -O1でコンパイル.
inline版 | call版 | 間接call版 | |
---|---|---|---|
通常 | 0.972 | 1.712 | 1.948 |
速度低下時 | 0.976 | 3.700 | 9.500 |
低下比率 | 1.00 | 2.16 | 4.88 |
inline版は遅くなってないけどcall版は遅く, 間接call版はより遅くなっていた.
まとめ : VMware 12.5.9でLinuxのSpectre対策kernelにupdateするときはVMwareを再起動したほうがよい.
追記 : 可能性としてはリアルマシンでもsoft rebootで同様の現象になるかは確認しないといけないな.
別CPUのリアルマシンで試したけど再現しなかった. やはりVMware特有の現象か.