メモリに制約のあるマイクロコントローラ用に、Cでヒープ割り当てアルゴリズムを実装しようとしています。私は自分が知っている2つのオプションに検索を絞り込みましたが、私は提案を非常に受け入れており、これに経験のある人からのアドバイスやコメントを探しています。
私の要件:
-速度は間違いなく重要ですが、二次的な懸念事項です。
-タイミングの決定論は重要ではありません-決定論的な最悪の場合のタイミングを必要とするコードのどの部分にも、独自の割り当て方法があります。
-主な要件はフラグメンテーション耐性です。デバイスはluaスクリプトエンジンを実行しています。これには、さまざまな割り当てサイズ(32バイトブロックで重い)が必要です。主な要件は、このデバイスがヒープを使用不可能な状態に変えることなく長時間実行されることです。
また注意:
-参考までに、128Kから16MBの範囲のメモリまたはメモリ(下端に焦点を当てた)を備えたCortex-MおよびPIC32パーツについて説明しています。
-コンパイラのヒープを使用したくないのは、1)すべてのコンパイラで一貫したパフォーマンスが必要であり、2)それらの実装は一般に非常に単純であり、断片化に関しては同じかそれより悪いためです。
-私が資金的に変更して再検証したくない巨大なLuaコードベースのために、二重の間接オプションが出ています。
これまでの私のお気に入りのアプローチ:
1)バイナリバディアロケータを用意し、メモリ使用効率を犠牲にします(2の累乗に切り上げます)。-これは(私が理解しているように)再チェーンのための高速バディブロックルックアップのためにメモリアドレスでソートされた空きノードを格納するために各注文/ビンのバイナリツリーを必要とします。
2)空きブロック用に2つのバイナリツリーを用意します。1つはサイズで並べ替え、もう1つはメモリアドレスで並べ替えます。(すべての二分木リンクはブロック自体に格納されます)-割り当ては、サイズによるテーブルのルックアップを使用して最適であり、アドレスによって他のツリーからそのブロックを削除します-割り当て解除は、再チェーンのためにアドレスによって隣接するブロックをルックアップします
-どちらのアルゴリズムでも、割り当てられたブロックの開始前に割り当てサイズを保存する必要があり、ブロックは2から4の累乗(または配置によっては8)で出力されます。(メモリアドレスでソートされた割り当てを追跡するためにバイナリツリーを他の場所に保存しない限り、これは適切なオプションとは見なされません)
-どちらのアルゴリズムにも、高さのバランスが取れたバイナリツリーコードが必要です。
-アルゴリズム2には、2の累乗に切り上げてメモリを浪費する必要はありません。
-どちらの場合でも、ネストされたビットフィールドによって割り当てられた32バイトブロックの固定バンクを使用して、このサイズ以下のブロックをオフロードします。これにより、外部の断片化の影響を受けなくなります。
私の質問:
-アプローチ1がアプローチ2よりも断片化の影響を受けにくい理由はありますか?
-要件に合う可能性のある、私が見逃している代替案はありますか?