5

DMAコントローラーのモジュロ機能を使用してリングバッファーを実装できるように、サイズに合わせて調整されたメモリバッファーを実現しようとしています。memalign を使用してこれを実行できることはわかっていますが、動的メモリを回避できたので、スタック上で実行できるかどうか疑問に思っています。私は GCC 4.4.1 を使用していますが、移植性 (組み込みシステム) は気にしません。

私は次のようなことをしたい:

template<uint16_t num_channels, uint16_t buffer_size>
class sampler {
    __attribute__((aligned(buffer_size * num_channels * 2)))
    uint16_t buffer[buffer_size][num_channels];
};

しかしもちろん、GCC は非定数アライメントを受け入れません (そして、アライメント > 8 は受け入れられない可能性があることを示しているようです)。

これを実現するために C++0x alignas() を使用できると思いますが、バージョン 4.8 まで GCC には表示されないようです。

1 つのオプションとして、バッファーのサイズを 2 倍にすることも考えられますが、それでは多くのスペースが無駄になるようです (このバッファーにデバイス メモリのかなりの部分を使用することを計画しています)。たぶん、あきらめて動的メモリを使用する必要があります。memalign は無駄なスペースという点で比較的効率的ですか?

何か案は?

4

4 に答える 4

5

ストレージのサイズを 2 倍にする必要はありません。追加するだけで済みます。(alignment - 1)基本的にはmemalign、バックグラウンドで行われていることと同じです。2 の累乗アライメントの場合:

char buf[size + (alignment -1)];
char *aligned = (char*)((intptr_t)buf + (alignment - 1) & ~intptr_t(alignment - 1));
于 2012-12-01T21:33:04.233 に答える
1

リンカコマンドファイルを使って久しぶりですが、こんな感じになると思います。

次のファイルbuffer.cppを作成します

char buffer[ BUFFER_SIZE ];

オブジェクトファイルには、.bss(初期化されていないデータ用)、. data(初期化されたデータ用)、および.text(実行可能コード用)という名前のセクションがあります。buffer []は初期化されていないため、.bssになります。

したがって、このような(gnu)リンカーファイルでうまくいくはずです

SECTIONS {
   .bss 0x0  : {
        buffer.o(.bss)
        *(.bss)
    }
   .data : {
        *(.data)
    }
   .text : {
        *(.text)
    }
}

0x0は、リンカーにアドレス0x0のbuffer[]をロードするように指示します。

于 2012-12-01T23:51:01.933 に答える
0

より大きいバッファを作成し、buffer_sizeその中のオフセットを計算して開始できますか?

于 2012-12-01T21:33:46.243 に答える
0

組み込みシステムにメモリ管理ユニットがある場合、特に実行ごとに 1 回だけ割り当てる場合は、動的メモリの賢明な使用を心配する必要はほとんどありません。

MMU がない場合は、リンカー マップ ファイルを使用して固定の場所を割り当てることを検討できます。

実際のオペレーティング システムを備えたシステムでは、いずれにせよ、DMA 互換バッファをカーネルによって特別に割り当てる必要がある場合があります。

于 2012-12-01T21:38:33.503 に答える