本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

GCCのgit移行が難航中

GCCはgitへの移行を計画しているが、GCCの既存のsubversionレポジトリをgitレポジトリに変換する作業が難航している。

GCCの移行作業を検証しているのは他ならぬEric S. Raymond(ESR)だ。

ESRお手製の変換ツール、reposurgeonはsubversionからgitへの変換ができる。

Resource page for reposurgeon 3.44

しかしGCCは30年もの歴史を持ち、そのsubversionレポジトリも複雑だ。

ESRはGCCのためにreposurgeonのバグを潰し、勢い変換しようと試みたが、意外な障害に出くわした。メモリ不足だ。

GCC's Conversion To Git Is Being Held Up By RAM, a.k.a. Crazy DDR4 Prices - Phoronix

ESRの所有する64GBのメモリを詰んだマシンではメモリ不足で処理できない。そしてDDR4メモリの値段は高騰している。GCCのビルドサーバーに128GBのメモリを詰んだものがあるからそれを使わせてくれとか、reposurgeonをPythonからGoに移植すればメモリ消費量は減らせる可能性があるが移植は困難を極めるとか、ESRに投げ銭してメモリを買わせようなどと議論をしていたのが7月はじめ。

さて、今はメモリ以外の問題に出くわしている。

GCC's Conversion To Git Is Still Turning Out To Be A Massive Headache - Phoronix

どうもGCCの膨大で複雑な歴史を正しくgitで表現する方法について議論の余地がある他、変換結果が壊れることもある。問題を解決したいが、変換自体がとても遅いため、デバッグが困難だという。

https://gcc.gnu.org/ml/gcc/2018-07/msg00322.html

トンネル出口の明かりが見えたと思ったら対抗列車が突っ込んできやがった。

もう変換はほぼほぼ終わりだと思っていたのに。俺はtrunkとブランチすべてがクリーンに変換されるのを確認したのに。捨ててもいいことに同意した失敗ブランチただ一つを除いては。

後残っているのはexecute-permission propagationとかmid-branch deleteをどうするかという問題だけで、前者はすでに解決済みだし、後者も解決に取り掛かっている。最終的には年末には、たぶん8月とか9月には、完了できるはずだったのに。

そしたらこのザマよ。俺の最新の変換がtrunkで間違った結果を出しやがった。これは実際ヤバイ問題で、GCCレポジトリがあまりにも巨大すぎるので調査するのに時間がかかりすぎる。SVNダンプファイルをreposurgeonで読み込むだけで4.5時間かかるし、フル変換に9時間はかかる。レポジトリは俺が最適化を考えるのと同じぐらい早く増大しているぜ。

しかも悪いことに、クリーンな変換ができるコミットまで戻っても失敗する。たぶん俺がへんてこなブランチコピーの対処を実装した結果こうなってるんだと思う。

パーティーに遅れてやってきた奴のために説明してやると、Subversionのダンプファイルの処理シーケンスの解釈は単純で検証も楽だ。ブランチコピー操作を除いてはな。ブランチコピーが他の操作に及ぼす影響だけはマジで闇が深い。

Subversionのコードが何をすべきかっていう正しいセマンティクスは存在するわけだが、古のSubversion開発者が理解していたことは、今や失われている。ダンプフォーマットはまともにドキュメント化されていない。今の不完全なドキュメントが存在する理由は、他でもない俺が解析したからだ。でも俺のドキュメントも疑問だらけだし、その疑問にはSubversion開発者も回答できないできる。

なのでレポジトリを変換する際にブランチコピーに関連した謎の挙動に出くわすのはよくあることだ。普通、おれは問題のコミットをbisectして、

  1. ダンプを問題が再現する最小のセグメントに切り取る
  2. content blobsをsource commitを識別できるunique small cookiesに置換する処理を行って結果が正しいことを検証
  3. topological reduceしブランチコピーもプロパティ変更でもない無価値なコミットを除去し、結果が正しいことを検証
  4. 手動で不必要なブランチをreposurgeonで削除

いつもなら、俺は今頃、問題を再現できる割と小さめのレポジトリ(今までで200コミットを超えたことはない)を作ってる。デバッグレベルを上げて変換を観察し、何が起こっているのかを観察する。そして問題を修正し、問題を再現する最小例は新たなテストケースになるって寸法だ。

これによって、ダンプファイル解析を着実に改善していき、Subversionのコードがやっていることをより忠実にエミュレートしていく。簡単な仕事ではないが、エッジケースを埋めていくほど楽になる。今まではこれでうまくいってきた。

GCCレポジトリのサイズでは、この戦略がうまくいかない。軽く計算するだけで、bisect一回で最短でも18日かかる。現実的には一ヶ月近くかかるだろう。

つまり、現状ではゲームオーバーで負けたってことだ。GCCレポジトリはでかすぎる上に変すぎる。

この問題を現実的に解決するには、俺のツールはすっげー速くなる必要がある。だいたい桁違いに早くないといかん。

ハードウェア性能を上げるのは無理だ。シングルプロセスを1.3GHz以上にあげたコンピューターはこの世に存在しないし、問題は並列化できない。

ソフトウェアの変更でうまく行く可能性はある。俺はreposurgeonをPythonからGoに移植するということについて考えている。repocutterで実験してみたところ、{Python版の40倍高速化した。reposurgeonではそんなに高速化するとは思えないが、問題を現実的に解決できるぐらいには高速化できるだろうと踏んでいる。40倍の半分だったとしても、9時間のテストランが13分になるわけだから。

この計画の問題点は、GOに移植するのは困難を極めるってことだ。めっちゃむずい。どのくらい時間がかかるかわからんが数カ月単位でかかる。

GCCはどのくらい辛抱強く待つのか決める必要があるな。現状だと、今のソースツリーの状態をそのままgitにしていちからはじめるほうがマシかもしれん。歴史は記録だけに留めるとして。