Fil-Cの驚愕GCでC言語の既存コードが超安全に!性能は本当に大丈夫?
引用元:https://news.ycombinator.com/item?id=45133938
Fil-Cって既存のCコードを安全にするのに超重要そう!CPythonやSQLiteとか、Rustで書き換えるのが難しい有名ソフトも対応してるのがマジでヤバいね。
MMUなしでFil-Cを使って、互いに信頼しないプロセス間でマルチタスクできるのかな?
実際に使った人いる?https://news.ycombinator.com/item?id=45134852だと4倍も遅くなるって報告もあるみたいだけど。
名前もウケるね!Feelthay!
MMUなしでのマルチタスクは可能だよ。FUGCはOSのMMU依存機能を使うけど、依存しないバージョンも作れるんだ。
4倍のスローダウンは俺が報告したワーストケース。リアルな測定にこだわってるからね。実際、お気に入りのソフトのFil-C版を使っても、ほとんど違いを感じないよ。
Fil-C版のソフトを動かすとき、missing free()みたいなバグを報告してくれるサニタイザーモードってある?それでバグを見つけたことある?
missing free()はGCが勝手に処理してくれるから、リークはメッセージなしで直っちゃうんだ。もちろん、ポートしたソフトでバグは見つけたことあるよ。
補足だけど、これはトレーシングGCなんだ。生きてるデータだけを訪れて、死んでるデータは訪れないから、デッドオブジェクトを報告するには特別なサポートがかなり必要になるよ。
Fil-Cカーネルでシステム全体を安全に単一アドレス空間で動かせたらすごいことになりそうだね。ハードウェア分離のオーバーヘッドをなくせば、ソフトウェアの安全チェックのオーバーヘッドを埋め合わせられるかも。昔のMicrosoft Singularityプロジェクトの夢みたいだ。
でも、プリコンパイルされたユーザープログラムがセキュリティ境界を守ってるか検証する方法がないから、結局全部ソースから自分でコンパイルしないと安全は保証できないかな。
えっ、そうなの?non-moving GCが死んだオブジェクトを訪れずにどうやって再割り当て可能にするんだろう?
コーディングエージェントが進歩すれば、Rustへのコード書き換えってマジで簡単になるよ。実績のあるリファレンス実装があれば、堅牢なものも楽に作れるはず。
数年後には、全部がRustに書き換えられても全然驚かないね。だって超簡単になるだろうから。
Proof Carrying Codeを使えば、バイナリがFil-Cのルールを使ってるって強制できるんじゃないかな。
なんでそんなものまで見に行く必要があるんだ?内部の管理(ビットマップとか)でアドレス範囲が利用可能になったってマークするだけだろ。
一般的に、死んだオブジェクトの数だけ新しく利用可能になるアドレス範囲があるんだから、この文脈ではそれらを「見に行く」ってことと同じだよ。
PCCはソフトウェア開発の現状には合わないと思う。ユーザーは性能を重視し、証明システムの複雑化はバグの温床になりがち。Javaの例もあるし、動的チェックの方が現実的だよ。開発者は不具合があればバグ報告を出すしね。
Proof Carrying Code (PCC) はランタイムで効率的だよ。検証器はインストール時に一度だけ動かせばよく、既存の証明の正当性をチェックするだけだから速い。証明システムを拡張したいなら、簡単な信頼できる公理を追加すればよくて、検証器を複雑にする必要はないんだ。Javaの複雑化は主に標準ライブラリの話で、PCCはJVMの基本型チェックに近いから心配ないよ。
検証器のランタイム性能は重要じゃないけど、チェックできる安全証明の「表現力」は重要だね。ロード時に証明できない特性はランタイムでチェックしなきゃいけないから。ArrayList<Price>からのダウンキャストやKotlinのnull可能性がいい例だ。JVMの基本型チェックの実装には、長年経ってから多くの穴が見つかってるんだよ。
それって「visit」の定義じゃないと思うな。俺は非移動型GCの言語を開発中で、サイズクラスを使ってメモリをスラブに割り当ててるんだ。占有状況はビットマップで管理してる。GCは生存ビットマップを作ってAND演算でメモリを解放する。死んだオブジェクトでスラブを埋め尽くしても、GCはこのスラブのどこもウォークせず、全てゼロの生存ビットマップでメモリを解放するだけだよ。
それはすごいプロジェクトだね!非移動型なのに世代別GCなの?プロジェクトの主な目標は何?生存ビットマップのアプローチはかなり広まってるよね。jemallocもそうだった気がする。それでも、この議論の文脈ではそれは「訪問」と数えられると思うよ:https://news.ycombinator.com/item?id=45137139
RustでSQLite: https://github.com/tursodatabase/turso
RustでCPython: https://github.com/RustPython/RustPython
RustでBash: https://github.com/shellgei/rusty_bash
これってIBM i(AS400ともいう)がやってることだと思うな。IBM iのアプリケーションはハードウェア非依存の中間表現TIMIにコンパイルされて、SLIC(カーネル)が通常プログラムインストール時にマシンコードにコンパイルするんだ。SLICはシステムセキュリティも担当してるから、悪意のあるユーザーが不正なプログラムを忍び込ませることはできないよ。
https://en.wikipedia.org/wiki/IBM_i
納得できないけど、仮に前のコメントが言うようなことがベストケースで起こったとしよう。それでもRustのポートは大量のunsafeコードを使う傾向があるから、メモリ安全性の脆弱性のオンパレードは続くことになる。一方で、Fil-Cにはunsafeな抜け道がないんだ。Fil-CはRustよりも安全だけど、その分遅くて重い選択肢だと考えたらいいよ。
Turso、RustPython、Rusty_bashの現状(TursoはAlpha版、RustPythonはPython標準ライブラリのサポート、Rusty_bashはテスト24/84パス)が書かれてるね。CPythonの実装がここまで進んでたのは驚きだよ!もっと進んでほしいな。
Turso says: https://rustpython.github.io/pages/whats-left
Rusty_bash says: [具体的なURLは不明]
お前が低評価されたのは、誰も屁理屈が好きじゃないからだよ。特にTursoプロジェクトはGitHub見れば分かるけど、めちゃくちゃ活発に開発されてて、クラウド版を売りたいから資金も入ってるんだ。SQLiteが3人でできたんだから、十分な資金と優秀なチームがあれば、これはちゃんと実現可能なプロジェクトだと思うよ。Tursoならそれができそうだね。
ゲーデルの定理が出て以来、”穴”がないシステムなんてありえないって、とっくに分かってることじゃん。
いや、それは間違いだよ。ゲーデルが示したのは、一貫性のある公理系の中にも証明できない定理があるってだけで、矛盾のない公理系が存在しないって言ったわけじゃないんだから。
LLMはコードをゼロから書くより、別言語に翻訳する方が得意だと感じてる。でも、今のLLMでPerlやLuaみたいなGC言語からRustに書き換えるのは、まだ「めちゃくちゃ簡単」とまでは言えないね。数年後には簡単になる可能性もあるけど、AIの進歩は予測不可能で、人類が絶滅したり、今のプログラミング言語が全部廃れたりする可能性だってあるんだから。
俺のコメントが+7にアップボートされてるのは、屁理屈じゃなくて、Rustでプロジェクトを書き換える今の状況を評価したからだよ。まだ実現してないってことね。理論的には可能だけど、Pythonプロジェクトは想像以上に進んでるみたいだけど、実際にやるのは難しいだろうね。
それは「訪問」とは違うと思うな。GC中にダーティビットマップを見るのはメモリ確保時だけで、GC中は見ないから、ダーティビットが別のオブジェクトを表してるかは分からないんだ。それを知るには、厳密なサイズクラスかオブジェクトヘッダが必要になる。ライブオブジェクトのビットマップと既存のものを比較してリークを検出する訪問パスを追加するのは簡単だっていう点では同意するよ。だいたい99%は意見が一致してるんじゃないかな。
最近、Rustとエージェントを使ってサービスホットコアを2つ書き換えたんだけど、速度が4倍から400倍以上(SIMDと精密なメモリ管理のおかげ)になったし、エージェントが書き換えたコードでほぼ完璧なテストカバレッジも得られたよ。だから俺の経験は圧倒的にポジティブだね。AIエンジニアリング能力では俺がちょっと先を行ってるかもしれないけど、もっと良いモデルやツールが出てくれば、この能力はすぐにみんなが手に入れるはずさ。
「Fil-Cを使ってMMUのないコンピュータで、互いに信頼できないプロセス間でマルチタスクをするのは実現可能なのかな?」
たとえ通常のデータフローがうまくいったとしても、それはコバートチャネルを生み出す原因になると思うよ。それに、プロセスの切り替え時に発生するMeltdown/Spectreの緩和策も、すぐに無効になってしまうんじゃないかな。
移動しないGCは、使われなくなったオブジェクトもちゃんと処理しないといけないんだよ。
それってWebAssemblyと基本的に同じアイデアじゃない?
もっとコメントを表示(1)
標準のmalloc/free(dlmallocとか)を使いたいなら、デッドオブジェクトを知る必要があるね。でもmallocライブラリをGCの仕組みに完全に統合すれば、その必要はなくなるよ。その方がずっと簡単だし速いだろうね、mallocをポインタのバンプだけで済ませられるからさ。
これ、研究に近いけど産業的にも役立つ、かなり珍しいプロジェクトって感じだね。すごくいい!普通なら、こんなのは大手テック企業から出てきそうだけどな。だから、このプロジェクトの最初の動機は何だったの?これが情熱プロジェクトじゃないとしたら、誰が資金を出してるの?何人年かかったの?最終的な目標は何?
>最終的な目標は何?
って質問だけど、著作権がEpic Gamesって書いてあるから、それが答えじゃないかな。
”Epic Gamesの言語エンジニアリングのシニアディレクター、Filip Pizloが独自のメモリセーフなC言語を作ったらしいよ。なんでかって?さあね!”
このリンクも見てみて。https://www.theregister.com/2024/11/16/rusthaters_unite_filc…いいね!
素晴らしいリンクだね、すごく必要な背景情報をありがとう!
このリンクはスレッドの一番上に置くべきだね!
Fil-Cがあるのは本当に素晴らしいね。これって実際のプログラムにすごく効果的な技術なのに、開発者たちは機能しないって思い込んでるんだ。存在証明は長い堂々巡りの議論を断ち切るからね。
ベンチマークどうなってんの?C/C++が人気な用途で、性能がGoとかと大差ないなら、Fil-Cを選ぶ意味なくない?スループット、レイテンシ、フットプリントが心配だね。
プログラムによっては通常と同じ速さで動くこともあるし、4倍遅くなることもある。だいたいはその中間くらいだね。
「C/C++が性能重視の用途で人気」ってのは誤解だろ。今使ってるC/C++コードの99%は性能を気にしないよ。オリジナルのコードがC/C++だったり、C/C++ライブラリに依存してたり、メモリやsyscallの抽象化レベルが最高だから使われてるんだ。シェルやテキストエディタがいい例だよ。
C/C++が新規プロジェクトで使われる理由は他にもあるけど、99%が性能やフットプリントに厳しくないってのは言い過ぎだろ。組み込み用途だとGCなんてコードサイズやレイテンシの問題で無理だし、そこでは新規でもCを使うことが多い。Chromeが2倍遅くなったらFirefoxに戻るわ。あれは性能重視のC++コードの塊だ。
V8みたいなJITをFil-C内で動かすとどうなる? 生成コードにジャンプする前に何らかの回避策が必要になりそうだけど、他に調整は要るの?
レイテンシが致命的だと思うよ。GCは100命令くらいのオーバーヘッドになることがあるし。
ほとんどのC/C++コードはデスクトップやサーバーOSで動いてるから、性能に余裕があるのが俺の経験だね。Linux、Windows、AppleのOSを使ってるなら、君もそう感じるはずだよ。
V8みたいなJITをFil-C内で動かすとどうなるかって? Fil-Cがパニックになるだろうね。Fil-CはPROT_EXECを許可しないからね。
全てのコードは性能に敏感だよ。
それに、どの言語も”Cと比べてたった2倍の遅さ”って主張するけど、結局C++でコーディングすることになるんだ。最初の点を見てくれよ。
これは並行GCだから、レイテンシで致命的になることはないよ。
命令数を数えるような使い方だとFil-Cの他の部分で困るだろうけどね。オーバーヘッドのほとんどはポインタチェイシングから来てるんだ。詳しくはhttps://fil-c.org/invisicapsを見てくれ。
そういうつもりはないんだ。俺はたくさんのプログラムをFil-Cに移植してきたし、そこで学んだことに反応してるだけだよ。でも気になるな。君が間違ってると思う、俺がしてる憶測って何だと思う?
- 4倍の遅さがユーザー体験に影響しないってこと。
- 俺のコードがUnixタイムシェアリングシステムで動いてるってこと。
- 俺がCやC++を使ってるのが、単に引き継いだコードだからってこと。
- Unixツールが効率的なプログラミングから恩恵を受けないってこと、syscallのせいだとしてもね。
- マルチスレッドGCが性能に良いってこと。(システムを共有してないって前提でね)
ブラウザ開発者として、C/C++コードのほとんどはパフォーマンスにそんなに敏感じゃないって言いたい。たとえ4倍遅くなっても、ほとんどの人は気づかないはずだよ(ブラウザの性能ってのは、マーケティングの連中が自慢するだけの数字で、実際はあんまり関係ない)。
99%のCコードって言ってるのは、普通の人がコンピューターを使う上での話であって、プロジェクトの依存関係としてじゃないからね。Fil-Cで君のC/C++プロジェクトをコンパイルしろとは言ってない。ただ、エンドユーザーとして使ってるほとんどのC/C++プログラムはFil-Cでコンパイルされても、使い心地が悪くなることはないってことさ。
「Concurrent」って、普通「最悪実行時間の有界性」は意味しないよね?特にシングルプロセッサの場合さ。この場合は違うの?
InvisiCapsは信じられないくらいすごいね。CHERIでさえ、ポインタのサイズは維持できなかったのに。
プログラムによっては約4倍のスローダウンがあるって?RLBoxなんかと比べるとどうなの?
“これは神話だよ。君が今使ってるC/C++コードの99%はパフォーマンスに敏感じゃない。”
これは違うと思うな。せいぜい“パフォーマンスに敏感”っていう定義がすごく歪んでるだけじゃない?俺の意見では、ほとんどのコードはパフォーマンスに敏感だよ。PythonやRubyで書かれたクソコードでさえね。もっと速くなってほしいもん。例えばAsciidoctorなんてどう?あれは“パフォーマンスに敏感”じゃないって?とんでもない!
俺の経験を勝手に決めつけないでくれてありがとう。でも、俺のPCには2倍遅くなったらほとんどのユーザーが怒り出すようなC/C++コードがたくさんあるよ。ブラウザはもう言ったけど、以下のCPUバウンドなプログラムが2倍遅くなったら、俺はかなりイライラするね。
*コンパイラ(clangを含む)
*ほとんどのインタプリタ(Python、Rubyなど)
*シミュレーション重視のビデオゲーム(その他いくつか)
*VSCode(Sublimeにしとけばよかった)
*科学計算ツール/ライブラリ
確かに、zshやbashが2倍遅くなっても気づかないだろうし、cpはI/Oバウンドだろうけどさ。でも、もし誰かがほとんどのプログラムを2倍速くする魔法のclangパスを作ったら、そいつは数世代に一度の天才として称賛されるはずだよ。“C/C++の性能なんて誰が気にするんだ?”なんて言われてお払い箱にはならない。C/C++を安全にするためにオーバーヘッドをトレードオフする場所がないとは言ってないけど、それをC/C++のニッチなユースケースとして扱うのは馬鹿げてる。
俺は2倍しか遅くならないなんて主張してないよ。測定したプログラムの中には4倍遅くなるものもあるんだ。4倍 > 2倍ね。Fil-Cの性能を誇張するつもりはないし、実際の性能コストを見極めるのはすごく面白いと思ってる!
“全てのコードは性能に敏感だ。”
それはあり得ないでしょ。MetaはPHP/Hackで動いてるけど、これらはとんでもなく遅いよ。君のブラウザで動くコードはJSだけど、Yolo-C++より40倍も遅いのに問題ないじゃん。他にも、C言語より4倍遅いどころか、めちゃくちゃ遅いコードを動かしてる例はたくさんあるんだから。
RLBoxと比べると?って話だけど、俺は知らないし、関係ないね。RLBoxは君のCコードをメモリ安全にはしてくれない。ただコンテナ化するだけさ。
例えば、データベースをRLBoxに入れたとしても、ハッカーはメモリ安全性のバグを使って機密データを破壊したり、抜き出したりできるんだ。
ブラウザエンジンをRLBoxに入れたとしても、ハッカーは君のPC全体を乗っ取れるよ。
―エンジンにRLBox以外のサンドボックスがなければ、メモリ内のバッファを(GPUドライバなどに)渡す際に破損させて、カーネルを乗っ取られるだろうね。RLBoxはその破損を許しちゃうんだ。だって、そのバッファはプログラムのメモリ内にあるわけだから。
―エンジンにRLBoxの上に別のサンドボックスがあるなら、悪い奴らはブローカーにメッセージを送るためのバッファを破損させて、そのブローカーを乗っ取るだろうね。RLBoxがない場合と全く同じさ。
Fil-Cはポインタケーパビリティモデルを使ってそれを厳密に強制するから、これら全てを防ぐんだ。
だから、RLBoxがFil-Cより無限に速くても、俺は気にしないね。
Chromeは悪い例だね。最もパフォーマンスに敏感な部分では、メモリ安全性のバグを減らすために明示的にトレーシングGC(Oilpanって呼ばれてるやつ)を使ってるんだ。そして残りの大部分がC++で書かれてるのは、単にChromeがC++を標準言語にしたからであって、より安全な言語に切り替えるより、カーネルサンドボックスやIPCに頼る方が楽だと考えてるからさ。
それはセキュリティに対してすごく二元的な見方だね。RLBoxみたいなものが「恐ろしい何でもありのC言語セキュリティ」から「たぶん大丈夫」にしてくれるケースは確かにあるんだ。例えば、脆弱性の一般的な原因である画像解析とかね。
だから、RLBoxのセキュリティ特性がそれほど厳密でなくても、パフォーマンスの質問は依然として重要なんだよ。
この議論は、どんな種類のソフトウェアについて話しているのかを明記しないと全く意味がないよ。
I/O待ちにほとんどの時間を費やすソフトウェアの場合、4倍のスローダウンは全く関係ないかもしれないね。ユーザーが使うソフトウェアの多くはそうだろうと俺は思うよ。例えば、イベントループがあって、1秒に1回0.5msの計算をする場合、同じ計算が2msになっても全く気づかないでしょ。
コンパイラの場合、そこまで意味がないかもしれない(性能面だけでなく、メモリの問題でプログラムが落ちても「十分に抑えられている」だろうし、比較的短命なプログラムだからメモリリークもあまり問題にならない)。
そして本当にCPUバウンドなプログラムもあるけど、デスクトップPCでCPUが長時間フル稼働してるのをどれくらいの頻度で見る?([1]君じゃなくて、ピズロネーターに返信して議論に参加してるだけだよ)
“Concurrent”が通常“最悪実行時間の有界性”を意味しないのは確かだね。でも、OSスケジューラ、異なるキャッシュ、ファイルシステム、ネットワークなど、複雑な相互作用がある通常のシリアルコードでも同じことが言えるよ。
他の言語で書かれた良いシェルやテキストエディタはたくさんあるよ。俺はGoでシェルを書いたけど、Zshよりも有能だぜ。
どんなコードでもパフォーマンスは大事だよ。でも、全てのコードが完璧に書かれるほど重要じゃないんだ。
IOバウンド神話ってよく聞くけど、ほとんどのソフトはIO処理より実行時間が長くなるんだぜ。C言語を使えば、データやIOリソースをもっとうまく制御して最適化できるんだ。
最悪実行時間(WCET)を気にするのは、キャッシュやOSがない環境でコードを動かす時が多いんだ。ファイルシステムもないようなところでGCのコードサイズを心配するんだろ?Johnが言ってたように、組み込み用途じゃGCは厳しいって話だな。
もっとコメントを表示(2)
デスクトップやサーバーOSにはパフォーマンスの余裕があるって言うけど、車や飛行機、食洗機とか色々な組み込みシステムではどうなの?現代世界を動かす組み込みコードは“プログラム”じゃないってことか?
RLBoxとFil-Cを「セキュリティ向上」って点で比較してるみたいだけど、違いが大きすぎるよ。RLBoxはコンテナ化技術で、Fil-Cはメモリ安全技術なんだ。両方重ねて使う世界だってあり得るんだぜ。
俺は今Linux From ScratchをFil-Cに移植してるんだけど、パフォーマンスやフットプリントで99%は問題ないって話、全然誇張じゃないぜ。複雑なシステムコールを使うコードは、CやC++以外で書くのは本当に大変なんだ。
『Zen of Assembly Programming』みたいな本があるように、昔はC/C++とパフォーマンスは結びつかなかったんだ。今のパフォーマンス神話は、何十年もの最適化と未定義動作(UB)利用の成果なんだぜ。.NETチームが証明してるように、JITやAOTコンパイラに力を入れれば、他の言語でも全然速くなれるんだから。
そうだよ、どっちも「セキュリティ向上」が目的だもん。違いは理解してるけど、単に「もっとセキュリティが欲しい」なら、どちらも妥当な選択肢だから、性能を比較するのは当然だろ。「リンゴとオレンジを比べる」って変な表現だよな、普通に比較できるじゃん?元々は「リンゴとカキ」だったらしいけど。
https://english.stackexchange.com/a/132907/114887
ソフトって入力→処理→出力の単純なもんじゃないんだ。常に動いてイベントに反応してる。IOとCPUの複雑な相互依存が実行時間を大きく制約するんだ。C言語で得る利点も、並列化を恐れて単純なモデルを選ぶことで失うことだってよくあるんだぜ。
既存のCプログラムで既にfree(…)呼び出しが”丁寧に”配置されてて、ポインターごとに別々の境界情報を持ってるのに、なんでGCじゃなくてロック&キー方式の一時的なチェックにしなかったのかな?ロック&キーならメモリ使用量がもっと予測しやすくなって、GCの性能オーバーヘッドやスケジューリングの悩みを避けられるはずじゃん?多分、キーを保存するスペースが大きすぎるとか、チェックに時間がかかりすぎるとか、マルチスレッド環境で競合問題が起きるとかかな?
https://acg.cis.upenn.edu/papers/ismm10_cets.pdf
ロック&キー方式だと、Fil-Cの持つ一番すごい特性、つまりケーパビリティモデルが完全にスレッドセーフで、普通のケースでは特別なアトミック操作やロックがいらないっていう部分がないと思うんだよね。
なるほど、ありがとう!すごいプロジェクトだね!
参照がない限り範囲外のポインター演算を許してるのが面白いね。それってコンパイラが利用すると知られてる未定義動作(UB)の一種だよ(https://stackoverflow.com/questions/23683029/is-gccs-option-…)。LLVM内でそういう最適化を無効にしてるの?それともFil-Cはポインターを「ポインターベース + 整数オフセット」に分解することで完全に避けてるの?もし後者なら、ポインターに特化した最適化を逃してないかな?
まず、LLVMはGCCほどUBを悪用しようとしないよ。あと、GCCがこれで通ってるのもなんか変だけどね。僕のLLVMパッチを見てみたらわかるけど:
- インストルメンテーションが走る前に、厳選された最適化パイプラインを動かしてる。
- FilPizlonatorがLLVM IRから、UBを使った最適化を許可するフラグを削除してる。
- Clang CodeGenといくつかのLLVMパスに、UBによる明白な問題を修正するために外科的な変更を加えたんだ。
でもさ、もしフラグ削除しかしてなかったとしても考えてみてよ。ピズロネーションの前のパスで最適化がされてたとしても、最悪の場合、それは論理エラーになるかFil-Cのパニックを引き起こすだけ。FilPizlonatorはUBを”メモリ安全なサブセット”に構造的に強く制限してるんだ。
僕はこれをGIMSOプロパティ(garbage in, memory safety out)って呼んでるよ。
C標準の正確な言い回しは知らないけど、GCCがほとんどのプログラムで問題を起こさない理由は、「配列オブジェクト」っていう言葉がコンパイル時にサイズがわかる配列、例えばint arr[4]
みたいなのを具体的に指してるからじゃないかなって思うんだ。範囲外ポインター演算をしてるほとんどのプログラムは、mallocやmmapみたいなのから来たポインターを使ってるから、それらは配列と似た意味合いを持つかもしれないけど、配列じゃないもんね。
うん、君の言う通りだと思うよ。
「FilPizlonatorがLLVM IRからUBを使った最適化を許すフラグを削除する。」って、それってちゃんと信頼できるの?それとも、パッチでバグを直す必要があった?LLVMには浮動小数点数で、バックエンドがコード生成中に渡された属性をちゃんと守ってくれないバグがあって、ユーザーレベルのフラグの挙動が破られちゃうんだよね。UBでも同じことがありそうだなって思うんだけど。
信頼できるよ。LLVMは型安全な言語やメモリ安全な言語のバックエンドとして使えるように設計されてるし、そういうフラグもそれらの言語のセマンティクスを正しく実装するために作られてるんだ(もちろん他のLLVMの落とし穴を避けるために、アグレッシブなチェックを入れる必要もあるけど、FilPizlonatorはそれもやってるよ)。
もちろんバグがないとは言い切れないけどね。でも僕は今のところ、この手のバグには遭遇してないし、たくさんのソフトウェアをテストしたんだ(https://fil-c.org/programs_that_work を見てみて)。
これ、マジですごいね!「pollcheckの高速パスはロードとブランチだけ」ってとこに注目したんだけど、ブランチを避けるためのナイスなテクニックとして、https://android-developers.googleblog.com/2023/11/the-secret… の「Implicit suspend checks」ってのがあったよ。
あー、それはポーリングチェックのよくある最適化だね。ほとんどの製品版JVMがやってると思う。俺はまだ高レベルで基本的な最適化が山積みだから、そういう低レベルな最適化には全然手を出せてないけどね!
昔MaxineVMでやったんだ。TLSが自分自身を指して、セーフポイントが同じレジスタへのロードになるようにね。でもこれだと、全てのセーフポイントやTLSを使う操作で依存ロードの連鎖ができて、OOEやIPCを悪くしそう。今Virgilにスレッドを追加してるんだけど、GCコードもVirgilで書かれてるから、GCコード内のセーフポイントをオフにできるように、TLSからのシンプルなロード+ブランチを使うつもりだよ。
彼らがやってること全部は理解できてないけど、参照されてるDoligez-Leroy-Gonthier paperは読んだことあるよ。誰かが非学術的な(たぶん?)文脈でこれを使ってるのが嬉しいね。あの論文は有望に見えたけど、アルゴリズムが複雑すぎて、学術界から出るなんて信じてなかった。理解するのにすごく時間がかかったし、理解した時でも実装できる自信はなかったな(今じゃもう全然理解してないけど)。
あの論文の関連技術をやってるのは俺だけじゃないと思うよ。DLGに近いものがいくつかの製品版JVMに搭載されてるはずだ。
へぇ、面白いね。複雑なJVMについてたくさん読んだけど、たぶん彼らが引用元を明記してなかったから、自分で関連付けることができなかったんだな。
プレーンなCに並行、非移動型GCをくっつけるって、かなりすごいことだね。もし中規模のCのコードベースを、メモリのバグを減らす代わりに実行時間を2〜3倍にできるなら、俺はそれを選ぶな。段階的な導入はどれくらい大変?ターゲットごと?それともツールチェーン全体を置き換える感じ?
Cとパフォーマンス、セキュリティが大好きだよ。このGCとCapability Enforcementを合わせると、すごく魅力的だね。もっと安全なCがどうなるか、Capabilityの概念をチラ見しながら何度か考えたことはあるけど、コンパイラのコードには近寄らない方がいいタイプだ。Windowsのサポートはどれくらい大変かな?