Bufory pamięci współdzielonej w C ++ bez naruszania surowych reguł aliasingu
Walczę z implementacją wspólnego bufora pamięci bez łamania surowych reguł aliasingu C99.
Przypuśćmy, że mam jakiś kod, który przetwarza niektóre dane i musi mieć trochę pamięci „scratch” do działania. Mógłbym napisać to jako coś w stylu:
void foo(... some arguments here ...) {
int* scratchMem = new int[1000]; // Allocate.
// Do stuff...
delete[] scratchMem; // Free.
}
Następnie mam inną funkcję, która wykonuje inne rzeczy, które również wymagają bufora scratch:
void bar(...arguments...) {
float* scratchMem = new float[1000]; // Allocate.
// Do other stuff...
delete[] scratchMem; // Free.
}
Problem polega na tym, że foo () i bar () mogą być wywoływane wiele razy podczas pracy i alokacja sterty w całym miejscu może być dość zła pod względem wydajności i fragmentacji pamięci. Oczywistym rozwiązaniem byłoby jednorazowe przydzielenie wspólnego, współdzielonego bufora pamięci o odpowiednim rozmiarze, a następnie przekazanie go do foo () i bar () jako argumentu, w stylu BYOB:
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!
// ...
}
Myślę, że mam teraz dwa pytania:
- W jaki sposób mogę zaimplementować wspólny wspólny bufor pamięci, który nie narusza reguł aliasingu?
- Mimo że powyższy kod narusza surowe reguły aliasingu, nie ma „krzywdy” przy aliasie. W związku z tym czy jakikolwiek sensowny kompilator może wygenerować (zoptymalizowany) kod, który nadal wpędza mnie w kłopoty?
Dzięki