2

私は、CILバイトコードを事前にコンパイルするシステムを設計しています。比較的シンプルに保ち、移植性を高めるために、システムはマシンコードの代わりにCソースコードを出力します(ただし、OOPなどのすべての高レベルの構造は除外されます)。その意図は、ターゲットプラットフォーム用の標準Cコンパイラをそのコードで使用して、最終製品を取得することです。

最初は、stop-the-worldなどの非常に単純なGCアプローチを使用するつもりです。ただし、アプリケーションは優れたパフォーマンスを必要としませんが、まともなパフォーマンスが必要であるため、最終的にはGCを変更する必要があります。

最終的には、ある種の書き込みバリアを必要とする、より洗練されたGCを目指しています。私はSATBとカードマーキングのアプローチを見てきましたが、実際に良いGCを計画する準備はまだできていません。後で効率的なGC書き込みバリアがインラインアセンブリを必要とし、Cを発行する目的を大幅に無効にすることを発見するためだけに、Cソースコードを発行することで自分自身を撃ちたくありません。

それで、私の質問は、典型的な書き込みバリアをCコードで効率的に実装できるかということです。Cコンパイラにはまともなオプティマイザがあると想定できます。結果として得られる「ソースコード」が完全に判読できないこともすでにわかっているので、明確さは重要ではありません。

ソースファイルをさらに肥大化させることを犠牲にして、おそらく合理的に実行できると思いますが、GCの設計やコンパイラの内部に精通している人々からの言葉をいただければ幸いです。

4

1 に答える 1

4

正確な世代移動またはコピーGCが必要だと思います。

Cで書き込みバリアを設定できます。例として、OcamlランタイムとMELTランタイムの両方に書き込みバリアを備えた世代別GCがあります。また、qishは、Cで動作する、書き込みバリアを備えた世代別のコピーGCです。

(ところで、MELTはGCCを拡張するためのドメイン固有言語であり、あなたがやりたいように、Cにコンパイルされます)

より重要な問題は、ローカルポインタをどのように保持するか(およびGCがそれらをどのように認識するか)です。これは、GCの正確な側面です。それらをいくつかのローカル構造にパックしたい場合があります。しかし、Cコンパイラ(GCCなど)の最適化が少し少ない場合があります。

最近のバージョンのMONOのソースコードを調べると、世代別のコピーGCがあります。チキンスキームの内部も見てください(Cコードも生成します)。

一部の(またはあなたの)特定のGC実装に適合するようにCコードジェネレーターを変更する必要があることに注意してください(各GCにはわずかに異なる不変条件と期待があるため)。末尾再帰にも注意してください(一部のCコンパイラ、特に最近のGCCは、限られたケースでそれらを最適化する場合があります)。

Qish、MELT、またはOcamlでは、書き込みバリア(C側)は、タッチされた各ポインタに対して呼び出されるいくつかのマクロ(またはインライン関数)によって実装されます。詳細は実装固有です。Cコードジェネレーターがそれらを処理する必要があります。

マルチスレッドGCは設計が難しく、単純なGCであってもデバッグには時間がかかり困難であることに注意してください。

于 2013-03-17T02:11:31.993 に答える