C99 の厳密なエイリアシング規則を破ることなく、共有メモリ バッファを実装するのに苦労しています。
一部のデータを処理するコードがあり、操作するために「スクラッチ」メモリが必要であるとします。次のように書くことができます:
void foo(... some arguments here ...) {
int* scratchMem = new int[1000]; // Allocate.
// Do stuff...
delete[] scratchMem; // Free.
}
次に、スクラッチ バッファーも必要とする他の機能を実行する別の関数があります。
void bar(...arguments...) {
float* scratchMem = new float[1000]; // Allocate.
// Do other stuff...
delete[] scratchMem; // Free.
}
問題は、操作中に foo() と bar() が何度も呼び出される可能性があり、あちこちにヒープ割り当てがあると、パフォーマンスとメモリの断片化の点で非常に悪い場合があることです。明らかな解決策は、適切なサイズの共通の共有メモリ バッファを一度割り当ててから、BYOB スタイルの引数として foo() と bar() に渡すことです。
void foo(void* scratchMem);
void bar(void* scratchMem);
int main() {
const int iAmBigEnough = 5000;
int* scratchMem = new int[iAmBigEnough];
foo(scratchMem);
bar(scratchMem);
delete[] scratchMem;
return 0;
}
void foo(void* scratchMem) {
int* smem = (int*)scratchMem;
// Dereferencing smem will break strict-aliasing rules!
// ...
}
void bar(void* scratchMem) {
float* smem = (float*)scratchMem;
// Dereferencing smem will break strict-aliasing rules!
// ...
}
2 つの質問があると思います:
- エイリアシング ルールに違反していない共有共通スクラッチ メモリ バッファを実装するにはどうすればよいですか?
- 上記のコードは厳密なエイリアシング ルールに違反していますが、エイリアスを使用しても「害」はありません。したがって、正常なコンパイラで (最適化された) コードが生成され、それでも問題が発生する可能性はありますか?
ありがとう