1

私は独自のコンパイラを構築してきましたが、その大部分は明らかにレジスタ アロケータであり、一時変数とマシン レジスタを可能な限り効率的に一致させます。x86 などのアーキテクチャでは、多くのレジスタがないため、変数をメモリ (スタック) に格納する必要がある多数のスピルがあります。大きすぎてレジスタに収まらないため、メモリに格納される変数もあります。

レジスタ アロケータが実際に再度呼び出され、メモリ内の変数が効率的に割り当てられるため、できるだけ多くのスペースが共有されます。本当の問題は、レジスタ アロケータがメモリ内の 2 つの変数を隣り合わせに配置するように制約する方法がないことです (これは、レジスタ アロケータが小さい変数をいくつかの小さい変数として割り当てることができるためです)。より大きな変数が収まるように、これを処理するアルゴリズムがあるかどうか疑問に思っています。それ以外の場合は、メモリを異なる領域に分割し、それぞれが異なるサイズの変数を保持する必要があります。

これを示す例を次に示します。

void f(){
    int32_t a, b;
    //something happens to a and b...
    int64_t c;
    //something happens to c...
}

この例では、変数が最適化されていないこと、c が定義されると a と b が役に立たなくなること、すべての変数がスタック メモリに割り当てられることを前提としています。明らかに、'c' が 'a' および 'b' が使用したのと同じメモリを使用するため、8 バイトのみを割り当てる必要がありますが、現在のバージョンのコンパイラでは 16 バイトが完全に割り当てられます。

私の質問は、さまざまなサイズのメモリに変数を効率的に割り当てるにはどうすればよいですか?

4

1 に答える 1

1

少なくとも x86 では、隣接するレジスタを結合する意味がないため、レジスタ アロケータがスタック領域を割り当てるのに十分な汎用性がないことは明らかです。

まさにそれを行うためにそれを拡張してみませんか? または、それを分割またはサブクラス化して、レジスタとスタックの割り当てを直接処理します。

スタック アロケータに関しては、スコープが重複していないために 2 つの変数が同じ割り当てを共有する可能性がある (まれな) ケースで使用されるスタックを最小化することは、通常、実行時間の効率が良くなく、スペースの効率も特に良くありません。スコープの移行時に追加のスタック領域を割り当ておよび割り当て解除する操作は、価値があるとは考えにくいです。リアルタイム処理の最も重要な部分でさえ、通常、数バイトのスタック スペースを削減するよりも、堅牢性と速度に関心があります。

于 2010-02-09T19:43:22.720 に答える