Buffers de memória compartilhada em C ++ sem violar regras estritas de alias
Eu estou lutando com a implementação de um buffer de memória compartilhada sem quebrar as regras de aliasing rigorosas do C99.
Suponha que eu tenha algum código que processe alguns dados e precise ter alguma memória 'scratch' para operar. Eu poderia escrever como algo como:
void foo(... some arguments here ...) {
int* scratchMem = new int[1000]; // Allocate.
// Do stuff...
delete[] scratchMem; // Free.
}
Então eu tenho outra função que faz algumas outras coisas que também precisam de um buffer de rascunho:
void bar(...arguments...) {
float* scratchMem = new float[1000]; // Allocate.
// Do other stuff...
delete[] scratchMem; // Free.
}
O problema é que foo () e bar () podem ser chamados várias vezes durante a operação e ter alocações de pilha em todo o lugar pode ser muito ruim em termos de desempenho e fragmentação de memória. Uma solução óbvia seria alocar um buffer de memória compartilhada comum de tamanho adequado uma vez e depois passá-lo para foo () e bar () como um argumento, estilo 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!
// ...
}
Eu acho que tenho duas perguntas agora:
Posso implementar um buffer de memória compartilhada comum que não viola as regras de alias?
- Mesmo que o código acima viole regras estritas de aliasing, não há nenhum 'dano' sendo feito com o alias. Portanto, qualquer compilador sensato pode gerar código (otimizado) que ainda me coloque em problemas?
obrigado