9

私はオペレーティングシステムを開発していて、カーネルをプログラミングするのではなく、カーネルを設計しています。このオペレーティングシステムはx86アーキテクチャを対象としており、私のターゲットは最新のコンピューターを対象としています。必要なRAMの推定数は256Mb以上です。

各スレッドのスタックをシステムで実行するのに適したサイズはどれくらいですか?最大長に達した場合にスタックを自動的に拡張できるようにシステムを設計する必要がありますか?

RAMのページが4kまたは4096バイトであることを正しく覚えていれば、それは私にはそれほど多くないように思えます。特に再帰を多く使用する場合は、一度に1000を超えるインテガーをRAMに入れたいと思う時期がはっきりとわかります。さて、本当の解決策は、プログラムがmalloc独自のメモリリソースを使用して管理することでこれを実行することですが、実際には、これに関するユーザーの意見を知りたいと思います。

4kは、最新のコンピュータープログラムをスタックするのに十分な大きさですか?スタックはそれよりも大きくする必要がありますか?スタックは、あらゆるタイプのサイズに対応するために自動拡張する必要がありますか?私は、実用的な開発者の観点とセキュリティの観点の両方からこれに興味を持っています。

4kはスタックには大きすぎますか?通常のプログラム実行を考えると、特にC ++のクラスの観点からmalloc/new、関数呼び出しでスローされるデータを最小限に抑えるために、優れたソースコードはクラスの作成時に必要なデータになりがちです。

私がまだ理解していないのは、プロセッサのキャッシュメモリのサイズです。理想的には、スタックは処理を高速化するためにキャッシュに存在すると思いますが、これを実現する必要があるかどうか、またはプロセッサが処理できるかどうかはわかりません。私はテスト目的で通常の退屈な古いRAMを使用することを計画していました。決められない。オプションは何ですか?

4

5 に答える 5

11

スタック サイズは、スレッドの実行内容によって異なります。私のアドバイス:

  • スレッドの作成時にスタック サイズをパラメーターにします (スレッドが異なれば実行する処理も異なるため、異なるスタック サイズが必要になります)。
  • スタックサイズを指定することに煩わされたくない人のために、合理的なデフォルトを提供します (4K は、スタックプロフリゲートが信号をかなり迅速に取得するようになるため、私のコントロールフリークにアピールします)
  • スタック オーバーフローを検出して対処する方法を検討してください。検出は難しい場合があります。ガード ページ (空のページ) をスタックの最後に配置することができますが、これは通常は機能します。しかし、あなたはその堀を飛び越えてその先にあるものを汚染し始めないように、悪い糸の振る舞いに頼っています. 一般的にはそうはなりません...しかし、それが本当にタフなバグをタフにする理由です。気密メカニズムには、コンパイラをハッキングしてスタック チェック コードを生成することが含まれます。スタック オーバーフローの処理に関しては、問題のあるスレッド (またはその守護天使、つまりあなたが OS 設計者であると判断した人) が実行される別の場所に専用のスタックが必要になります。
  • スタックの端を独特のパターンでマークすることを強くお勧めします。これにより、スレッドが端を超えて実行された場合 (そして常にそうです)、少なくとも事後分析を行って、何かが実際にその端から実行されたことを確認できます。スタック。0xDEADBEEF などのページが便利です。

ちなみに、x86 のページ サイズは通常 4k ですが、必ずしもそうである必要はありません。64k サイズまたはそれ以上のサイズを使用できます。ページを大きくする通常の理由は、TLB ミスを避けるためです。繰り返しますが、カーネル構成または実行時パラメーターにします。

于 2008-10-13T05:10:57.840 に答える
2

Linux カーネル ソース コードで KERNEL_STACK_SIZE を検索すると、それがアーキテクチャに大きく依存していることがわかります - PAGE_SIZE や 2*PAGE_SIZE など (以下は一部の結果です - 多くの中間出力は削除されています)。

./arch/cris/include/asm/processor.h:
#define KERNEL_STACK_SIZE PAGE_SIZE

./arch/ia64/include/asm/ptrace.h:
# define KERNEL_STACK_SIZE_ORDER        3
# define KERNEL_STACK_SIZE_ORDER        2
# define KERNEL_STACK_SIZE_ORDER        1
# define KERNEL_STACK_SIZE_ORDER        0
#define IA64_STK_OFFSET         ((1 << KERNEL_STACK_SIZE_ORDER)*PAGE_SIZE)
#define KERNEL_STACK_SIZE       IA64_STK_OFFSET

./arch/ia64/include/asm/mca.h:
    u64 mca_stack[KERNEL_STACK_SIZE/8];
    u64 init_stack[KERNEL_STACK_SIZE/8];

./arch/ia64/include/asm/thread_info.h:
#define THREAD_SIZE         KERNEL_STACK_SIZE

./arch/ia64/include/asm/mca_asm.h:
#define MCA_PT_REGS_OFFSET      ALIGN16(KERNEL_STACK_SIZE-IA64_PT_REGS_SIZE)

./arch/parisc/include/asm/processor.h:
#define KERNEL_STACK_SIZE   (4*PAGE_SIZE)

./arch/xtensa/include/asm/ptrace.h:
#define KERNEL_STACK_SIZE (2 * PAGE_SIZE)

./arch/microblaze/include/asm/processor.h:
# define KERNEL_STACK_SIZE  0x2000
于 2011-05-14T13:03:22.200 に答える
1

仮想メモリを使用している場合は、スタックを拡張可能にする必要があります。QthreadsやWindowsFibersのようなユーザーレベルのスレッドで一般的であるように、スタックサイズの静的割り当てを強制することは混乱です。使いにくく、クラッシュしやすい。最近のすべてのOSは、スタックを動的に拡張します。通常、現在のスタックポインタの下に書き込み保護されたガードページを1つか2つ持つことで考えられます。そこに書き込み、スタックが割り当てられたスペースを下回ったことをOSに通知し、その下に新しいガードページを割り当てて、ヒットしたページを書き込み可能にします。1ページを超えるデータを割り当てる単一の関数がない限り、これは正常に機能します。または、2つまたは4つのガードページを使用して、より大きなスタックフレームを許可することもできます。

スタックサイズを制御する方法が必要で、目標が本当に制御された効率的な環境であるが、Linuxなどと同じスタイルのプログラミングを気にしない場合は、毎回タスクが開始されるシングルショット実行モデルを選択してください。関連するイベントが検出され、実行が完了してから、永続データがタスクデータ構造に格納されます。このようにして、すべてのスレッドが単一のスタックを共有できます。自動車制御などの多くのスリムなリアルタイムオペレーティングシステムで使用されます。

于 2008-10-13T06:18:23.880 に答える
1

ボールを転がすために 2 セントを投入します。

  • 「典型的な」スタックサイズがどうなるかはわかりません。おそらくスレッドあたり 8 KB だと思います。スレッドがこの量を超えた場合は、例外をスローします。ただし、これによると Windows にはスレッドごとに 1MB の既定の予約済みスタック サイズがありますが、一度にすべてがコミットされるわけではありません (ページは必要に応じてコミットされます)。さらに、コンパイラ ディレクティブを使用して、コンパイル時に特定の EXE に対して異なるスタック サイズを要求できます。Linux が何をしているのかはわかりませんが、4 KB スタックへの参照を見てきました (ただし、これはカーネルをコンパイルするときに変更できると思いますが、デフォルトのスタック サイズはわかりません...)

  • これは最初のポイントにつながります。おそらく、各スレッドが取得できるスタックの量に固定の制限が必要です。したがって、スレッドが現在のスタック スペースを超えるたびに自動的に追加のスタック スペースを割り当てたくない場合があります。これは、無限再帰でスタックするバグのあるプログラムが、使用可能なすべてのメモリを使い果たしてしまうためです。

于 2008-10-13T05:12:58.147 に答える
0

スタック サイズを構成可能な項目にして、プログラムと共に保存するか、プロセスが別のプロセスを作成するときに指定しないのはなぜですか?

これを構成可能にする方法はいくつもあります。

「0、1、または n」というガイドラインがあります。これは、オブジェクトの 0、1、または任意の数 (メモリなどの他の制約によって制限される) を許可する必要があることを意味します。これは、オブジェクトのサイズにも適用されます。

于 2008-10-13T05:10:09.823 に答える