Uma coisa que eu gosto bastante no C++ e que poucas vezes é visto com o devido cuidado é a forma como a memória é alocada. Eu ouço constantemente o mantra: Hoje temos muita memória disponível, um pouco a mais não faz diferença.
Opa, perai.
É verdade que é comum encontrarmos máquinas com 16, 32, 48 GB de memória, mas quando se fala de performance é também importante usar o mínimo possível de memória para um melhor aproveitamento do cache do processador.
Vejamos um caso de memória perdida por causa de alinhamento do processador.
Temos a struct:
https://gist.github.com/thiagomg/2da2f7f2d858144c60aa
Temos nela um int de 4 bytes + char de 1 byte = 5 bytes. Ah, quase esqueci, temos mais 3 bytes de alinhamento.
Isso acaba não sendo perceptível também nos casos onde a perda ocorre no meio da struct
https://gist.github.com/thiagomg/c2e50921f1682a0198d6
Tal qual o exemplo anterior, foram perdidos 3 bytes nesse exemplo, ou seja, 37,5% de espaço perdido. Um descuido no layout de uma struct pode ser até catastrófico!
Vejamos o exemplo:
https://gist.github.com/thiagomg/29ac6a6778af5703a0c8
Tivemos no exemplo acima 6 bytes perdidos, 50% do tamanho da struct. Isso pode fazer muita diferença quando um cálculo de uso de memória subir de 2 GB para 4 GB (sem contar fragmentação de memória e custo do alocador new).
A solução para isso é bem simples. Uma melhor disposição da struct resolve o problema.
https://gist.github.com/thiagomg/78141b878f519103b888
Veja só ! Metade do tamanho.
Eu poderia ter nesse cálculo também mais 4 ou 8 bytes de um ponteiro para uma vtable, mas esse é assunto para outro post.
Código: https://github.com/SimplyCpp/examples/blob/master/sizes.cpp
Opa, perai.
É verdade que é comum encontrarmos máquinas com 16, 32, 48 GB de memória, mas quando se fala de performance é também importante usar o mínimo possível de memória para um melhor aproveitamento do cache do processador.
Vejamos um caso de memória perdida por causa de alinhamento do processador.
Temos a struct:
https://gist.github.com/thiagomg/2da2f7f2d858144c60aa
Temos nela um int de 4 bytes + char de 1 byte = 5 bytes. Ah, quase esqueci, temos mais 3 bytes de alinhamento.
int:0-4, char:4-5 => Total bytes: 8
0 0 0 0 0 ff ff ff Wasted bytes: 3
Isso acaba não sendo perceptível também nos casos onde a perda ocorre no meio da struct
https://gist.github.com/thiagomg/c2e50921f1682a0198d6
char:0-1, int:4-8 => Total bytes: 8
0 ff ff ff 0 0 0 0 Wasted bytes: 3
Tal qual o exemplo anterior, foram perdidos 3 bytes nesse exemplo, ou seja, 37,5% de espaço perdido. Um descuido no layout de uma struct pode ser até catastrófico!
Vejamos o exemplo:
https://gist.github.com/thiagomg/29ac6a6778af5703a0c8
char:0-1, int:4-8, char:8-9 => Total bytes: 12
0 ff ff ff 0 0 0 0 0 ff ff ff Wasted bytes: 6
Tivemos no exemplo acima 6 bytes perdidos, 50% do tamanho da struct. Isso pode fazer muita diferença quando um cálculo de uso de memória subir de 2 GB para 4 GB (sem contar fragmentação de memória e custo do alocador new).
A solução para isso é bem simples. Uma melhor disposição da struct resolve o problema.
https://gist.github.com/thiagomg/78141b878f519103b888
int:4-5, char:0-4, char:5-6 => Total bytes: 8
0 0 0 0 0 0 ff ff Wasted bytes: 2
Veja só ! Metade do tamanho.
Eu poderia ter nesse cálculo também mais 4 ou 8 bytes de um ponteiro para uma vtable, mas esse é assunto para outro post.
Código: https://github.com/SimplyCpp/examples/blob/master/sizes.cpp
Comentários
Postar um comentário