8

特定のグローバル配列をゼロに初期化しないようにGCCに指示する方法はありますか?

コードが管理する大きなデータ構造を格納するために大量のメモリを予約したいので、次のように言います。

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB];

問題は、crtinit()がこのスペースをゼロに初期化するのに100万年かかることであり、それはまったく必要ありません。

そのスペースを初期化しないように強制する方法はありますか?

現在、リンカが認識している範囲外のメモリアドレスをハードコーディングしていますが、これは特に堅牢な方法ではありません。

さらに、これは遅い組み込みproc(50MHz Microblaze)なので、私がPCについて話していると思い込まないでください。そのスペースをゼロにするのに本当に長い時間がかかります。

4

4 に答える 4

8

属性を使用してgcc、オブジェクトを別の新しいメモリセクション(たとえば、.noinitメモリセクションなど)に格納できます。

 BYTE mChunkSpace[SIZE_16_MB] __attribute__ ((section (".noinit")));
于 2012-06-24T20:37:34.560 に答える
4

動的初期化を試してください:

BYTE* mChunkSpace = (BYTE*)malloc(SIZE_16_MB * sizeof(BYTE));

次に、このデータは初期化されておらず、初期化されるのを待っています。

于 2012-06-24T20:29:50.917 に答える
2

SOでここで得られるほとんどの回答は、汎用プラットフォーム(つまり、WindowsまたはLinuxを問わずPC)の両方でVisual StudioまたはGCCのいずれかに傾いており、「標準では...」の引用に重きを置いています。組み込みLinuxまたはWindowsCEを実行している場合を除いて、いずれも小さな組み込みシステムにはそれほど当てはまりません。

ouahの答えは、おそらくあなたが必要としているものに最も近いものです...あなたが本当にGCCを使用しているのであれば、おそらくまさにあなたが必要としているものです。必要なメモリチャンクは非常に大きく、おそらくシステムのメモリの大部分を消費するため、ビルドのリンカコマンドファイルに特別なセクションを定義するか、C、C ++、またはアセンブリファイルのいずれかでリンカディレクティブを使用するのが最善の策です。 。そのための構文は、コンパイラによって異なります。ソース/アセンブリファイルでリンカーディレクティブを使用する場合、メモリ領域の読み取り/書き込み機能などに関して指定する必要のある属性が存在する可能性があります。MicroblazeにMMU /メモリコントローラーがない場合は、おそらくそうではありません。 。セクションの先頭にリンカーシンボルを配置する必要があります。Cコードには、「externcharsymName[]」ディレクティブを使用して、リンカーがセクションの実際のアドレスで上書きするrelocでCコードをコンパイルできるようにします。コンパイラとアーキテクチャによっては、ある種の「far」属性を使用してsymName[]externを宣言する必要がある場合もあります。Microblazeについては、それについて何も言うことができません。

于 2012-06-24T20:58:52.553 に答える
-1

この規格では、宣言の時点で明示的に初期化されていない静的データはゼロで初期化されると規定されています。最初の要素をゼロ以外の値に自分で初期化することにより、実行時の初期化を回避できます。

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB] = {1};

を指定すると、コンパイラはそれをセクション0に格納する可能性が高いことに注意してください。つまり、実行時に初期化されたままになります。.bssこれを行う必要はありませんが、そうしないのはばかげています。これで、配列が.dataセグメントにスローされます。

もちろん、これにより、結果の実行可能ファイルがはるかに大きくなります(正確には、約16MB大きくなります)が、実行時にメモリは初期化されません。ですから、問題はあなたにとって何が重要かということになります。そのメモリをゼロにするのに必要な時間、または結果の実行可能サイズ?

于 2012-06-24T20:26:01.870 に答える