4

したがって、次のようなコードがあります。

uint8_t *buffer = <16 MB memory region>
uint32_t count = 1024;
uint32_t position = 0;

uint8_t *get_data() {

    uint8_t *region = buffer + position * 16;

    position += 1;
    position %= count;

    do {
        __sync_synchronize();
    } while (reigon[0] != 1);

    return region;
}

問題のバッファは、ハードウェア デバイスによって書き込まれています。ある時点 (おそらくループを開始する前、または開始した後) で、ハードウェアはその場所と残りのバッファーに書き込みます。

現在、__sync_synchronize を使用してメモリ バリアを発行しています。これは、コンパイラがそのメモリ領域の残りの部分を以前からキャッシュする方法がないことを確認したいからregion[0] == 1です。

バッファ全体を揮発性としてマークできることは承知しています。ただし、この関数から不揮発性バッファを返せるようにしたいと考えています。

だから、それを行う方法はありますか__sync_synchronize、しかしそれは私が指定したメモリの範囲だけを対象にしています。この場合、[region, region + 1024)?からのメモリ

余談ですが、このコードはユーザー空間に存在します。メモリ バッファは、カーネル モジュールで割り当て、ユーザー空間にマップし、FPGA に最終的に DMA するように指示したメモリの固定領域です。これは本質的に、DMA 転送を完了する FPGA にポーリング メカニズムを実装しようとしています。

4

2 に答える 2

2

リージョン限定のメモリ フェンスは、かなり珍しいアーキテクチャ機能です。ただし、ループが終了した後にのみフェンスが必要です。

while (*(volatile uint8_t *)region != 1)
    ;

__sync_synchronize();
return region;
于 2011-09-30T05:49:21.520 に答える
0

これでうまくいくはずです:

uint8_t *get_data() {    
    uint8_t *region = buffer + position * 16;
    volatile uint8_t *volatile_region = region;

    position += 1;
    position %= count;

    do {
    } while (volatile_region[0] != 1);

    return region;
}
于 2011-09-30T04:18:04.443 に答える