いけむランド

はてダからやってきました

binutils-2.41 performance regression

cygwin の binutils を 2.40 から 2.41 にアップデートしたら、めっちゃ遅くなった (ように見える。)

ruby の HEAD を毎晩 CI しているが、今月に入ってから急にコケだして、なんだろうと思ったところが始まりで、ログをダウンロードしてみると、制限時間の 1h を使い切って timeout しており、途中に異常に時間がかかっている処理を見つけた。

[00:27:53] ./miniruby.exe -I./lib -I. -I.ext/common  ./ext/extmk.rb --make='make' \
[00:27:53]  --command-output=ext/bigdecimal/exts.mk --dest-dir="" --extout=".ext" --ext-build-dir="./ext" --mflags="" --make-flags=" -- V=1" --gnumake=yes --extflags="" --make-flags="MINIRUBY='./miniruby.exe -I./lib -I. -I.ext/common '" --extstatic  \
[00:27:53]  -- configure ext/bigdecimal
[00:27:53] ../.././ext/bigdecimal/extconf.rb
[00:53:20] ./miniruby.exe -I./lib -I. -I.ext/common  ./ext/extmk.rb --make='make' \
[00:53:20]  --command-output=ext/cgi/exts.mk --dest-dir="" --extout=".ext" --ext-build-dir="./ext" --mflags="" --make-flags=" -- V=1" --gnumake=yes --extflags="" --make-flags="MINIRUBY='./miniruby.exe -I./lib -I. -I.ext/common '" --extstatic  \
[00:53:20]  -- configure ext/cgi
[00:53:20] ../../.././ext/cgi/escape/extconf.rb

ruby の bigdecimal を見てみたが、最近に変更が入ったようには見えない。

手元でやってみると bigdecimal でたしかに長時間止まる。

ちなみに前日の CI では多少は時間がかかっているものの timeout させるようなものではなかった。

[00:18:07] ./miniruby.exe -I./lib -I. -I.ext/common  ./ext/extmk.rb --make='make' \
[00:18:07]  --command-output=ext/bigdecimal/exts.mk --dest-dir="" --extout=".ext" --ext-build-dir="./ext" --mflags="" --make-flags=" -- V=1" --gnumake=yes --extflags="" --make-flags="MINIRUBY='./miniruby.exe -I./lib -I. -I.ext/common '" --extstatic  \
[00:18:07]  -- configure ext/bigdecimal
[00:18:07] ../.././ext/bigdecimal/extconf.rb
[00:19:45] ./miniruby.exe -I./lib -I. -I.ext/common  ./ext/extmk.rb --make='make' \
[00:19:45]  --command-output=ext/cgi/exts.mk --dest-dir="" --extout=".ext" --ext-build-dir="./ext" --mflags="" --make-flags=" -- V=1" --gnumake=yes --extflags="" --make-flags="MINIRUBY='./miniruby.exe -I./lib -I. -I.ext/common '" --extstatic  \
[00:19:45]  -- configure ext/cgi
[00:19:45] ../../.././ext/cgi/escape/extconf.rb

そもそも ruby の commit を CI できてた↑の状態にしても、手元だと bigdecimal で止まるため、要因は他にありそうと思い、ログの他の部分の diff をとってみたら、ビルドするためにインストールするパッケージにいくつかの違いがあり、その中に binutils のバージョンアップがあった。

@@ -205,7 +205,7 @@
   165   erase dash                                   0.5.9.1-1                
   166 install cygrunsrv                              1.64-1                   
   167   erase cygrunsrv                              1.62-1                   
-  168 install binutils                               2.40-1                   
+  168 install binutils                               2.41-1                   
   169   erase binutils                               2.29-1                   
   170 install base-cygwin                            3.8-2                    
   171   erase base-cygwin                            3.8-1                    

手元で動かしている最中に雑にタスクマネージャーを開くと、ld が長時間居座ってるように見えた。

本当はきちんとプロファイルをとって確認するべきだったけど、結果的に他の cygwin パッケージメンテナから binutils 本家にバグレポが投げられてため、間違ってはいなかったらしい。

lists.gnu.org

ミニマムな再現方法の切り出しをしたいけど、そもそも extrconf.rb の中で何をやってるから調べないといけないなあ。 それかバグレポで挙がってる、protobuf から切り出した方が早いか...。

追記 (2023-09-30)

この記事を書いて、しばらくしたら、解決してた。対応版 (2.41 以降のリリースはされていないため、とりあえずパッチを当てたもの) も cygwin 公式にアップロードされてた。

www.mail-archive.com

sourceware.org