関数型言語をハードウェアに直接結び付ける方法を考えていて、ガベージ コレクションのハードウェア実装について疑問に思っていました。
これにより、一部の環境のランタイムではなく、ハードウェア自体がすべてのコレクションを暗黙的に処理するため、処理速度が大幅に向上します。
これは LISP Machines が行ったことですか? この考えについて、これ以上の研究はありますか?これもドメイン固有ですか?
考え?異議?議論。
関数型言語をハードウェアに直接結び付ける方法を考えていて、ガベージ コレクションのハードウェア実装について疑問に思っていました。
これにより、一部の環境のランタイムではなく、ハードウェア自体がすべてのコレクションを暗黙的に処理するため、処理速度が大幅に向上します。
これは LISP Machines が行ったことですか? この考えについて、これ以上の研究はありますか?これもドメイン固有ですか?
考え?異議?議論。
Generational Collection のおかげで、トレースとコピーはGC の大きなボトルネックではないと言わざるを得ません。
役立つのは、スタックスキャンを実行してヒープをマークするときに「世界を止める」一時停止の必要性を取り除くハードウェア支援の READ バリアです。
Azul Systems はこれを行いました: http://www.azulsystems.com/products/compute_appliance.htm 彼らは JavaOne でプレゼンテーションを行い、ハードウェアの変更により完全に一時停止のない GC がどのように可能になったかについて説明しました。
別の改善点は、記憶されたセットを追跡するためのハードウェア支援の書き込みバリアです。
世代別 GC は、G1 やガベージ ファーストの場合はなおさらですが、パーティションのみをスキャンし、クロスパーティション ポインターの記憶セットのリストを保持することで、スキャンする必要があるヒープの量を減らします。
問題は、ミューテーターがポインターを設定するたびに、適切な再記憶されたセットにエントリを配置する必要があることです。そのため、GC を実行していないときでも (小さな) オーバーヘッドがあります。これを減らすことができれば、GC に必要な一時停止時間と全体的なプログラム パフォーマンスの両方を減らすことができます。
明らかな解決策の1つは、使用可能なRAMよりも大きいメモリポインタ(たとえば、32ビットマシンの34ビットポインタ)を使用することでした。または、RAMが16MB(2 ^ 24)しかない場合は、32ビットマシンの最上位8ビットを使用します。ETHチューリッヒのOberonマシンは、RAMが安くなりすぎるまで、このようなスキームを使用して多くの成功を収めました。それは1994年頃だったので、その考えはかなり古いものです。
これにより、オブジェクトの状態を保存できるビットがいくつか提供されます(「これは新しいオブジェクトです」や「このオブジェクトに触れたばかりです」など)。GCを実行するときは、「これは新しい」オブジェクトを優先し、「触れたばかり」は避けてください。
2 ^ 64バイトのRAM(= 2^67ビット;宇宙には約10^80〜2 ^ 240の原子があるため、これまでにそれほど多くのRAMを使用できない可能性があるため、これは実際にルネッサンスを見る可能性があります。)。これは、VMがOSにメモリのマッピング方法を指示できる場合、今日のマシンで数ビットを使用できることを意味します。
はい。これら 2 つの論文の関連する作業セクションを見てください。
https://research.microsoft.com/en-us/um/people/simonpj/papers/parallel-gc/index.htm http://www.filpizlo.com/papers/pizlo-ismm2007-stopless.pdf
またはこれで:
http://researcher.watson.ibm.com/researcher/files/us-bacon/Bacon12StallFree.pdf
あなたは大学院生ですね。FPGA 設計とコンピューター アーキテクチャを調べてください。http: //www.opencores.org/ には無料のプロセッサ設計がたくさんあります。
ガベージ コレクションは、バックグラウンド タスクとして実装できます。これは、既に並列操作を目的としています。
ピート
本当に効率的な GC を実現するには GC 対応の仮想メモリ マネージャーが必要であり、最近ではほとんどがハードウェアによって VM マッピングが行われていることを説明するラムダ ザ アルティメットに関する記事がありました。はい、どうぞ :)
いくつかのプロトタイプが存在するはずだと私はかなり確信しています。ただし、ハードウェア固有の機能を開発および作成するには、非常に費用がかかります。MMUまたはTLBをハードウェアレベルで実装するには非常に長い時間がかかりましたが、これらは非常に簡単に実装できます。
GCは大きすぎて、ハードウェアレベルに効率的に実装できません。
おそらく、ここで必要な最も関連性の高いデータは、現在どのくらいの時間(CPU時間のパーセンテージ)がガベージコレクションに費やされているかということです。問題がない可能性があります。
この後、ハードウェアが「背後」のメモリにだまされていることを考慮する必要があります。現代の用語では、これは「別のスレッド」になると思います。一部のメモリは、調べている場合は使用できない可能性があり(デュアルポートメモリで解決できる可能性があります)、HWGCが何かを移動する場合は、他のプロセスをロックアウトして、それらに干渉しないようにする必要があります。 。そして、使用しているアーキテクチャと言語に適合する方法でそれを行います。つまり、ドメイン固有です。
表示されたばかりのものを見てください...別の投稿で...JavaのGCログを見てください。
最大の問題は、CPU レジスタとスタックです。GC 中にしなければならないことの 1 つは、システム内のすべてのポインターをトラバースすることです。つまり、それらのポインターが何であるかを知ることです。これらのポインターのいずれかが現在 CPU レジスターにある場合は、それもトラバースする必要があります。スタックにポインタがある場合も同様です。したがって、すべてのスタック フレームには、何がポインターで何がポインターでないかを示す何らかのマップが必要であり、GC トラバースを実行する前に、ポインターをメモリに取得する必要があります。
スタックが突然単純な LIFO 構造でなくなるため、クロージャーと継続の問題にも遭遇します。
明らかな方法は、CPU スタックまたはレジスターにポインターを保持しないことです。代わりに、各スタック フレームをその前のフレームを指すオブジェクトとして保持します。しかし、それはパフォーマンスを殺します。
80 年代に MIT の何人かの偉大な頭脳が、Scheme の方言を直接解釈し、LISP DSL で設計され、hardware-gc が組み込まれた SCHEME-79 チップを作成しました。
なぜ「物事をスピードアップ」するのですか?ハードウェアは正確に何をすべきですか?オブジェクト間のすべての参照をトラバースする必要があります。つまり、メイン メモリ内の大量のデータを処理する必要があり、これが時間がかかる主な理由です。これによって何が得られますか?ハードウェアのサポートにより、より速く実行できると思われる特定の操作はどれですか? ガベージ コレクターでの作業のほとんどは、ポインター/参照をたどるだけで、ライブ オブジェクトをあるヒープから別のヒープにコピーすることもあります。これは、CPU が既にサポートしている命令とどう違うのですか?
そうは言っても、なぜガベージ コレクションを高速化する必要があると思いますか? 最新の GC はすでに非常に高速かつ効率的であり、基本的には問題が解決されています。