Por que a velocidade do memcpy () diminui drasticamente a cada 4KB?
Eu testei a velocidade dememcpy()
percebendo que a velocidade cai drasticamente em i * 4KB. O resultado é o seguinte: o eixo Y é a velocidade (MB / segundo) e o eixo X é o tamanho do buffer paramemcpy()
, aumentando de 1 KB para 2 MB. As configurações 2 e 3 detalham a parte de 1 KB-150 KB e 1 KB-32 KB.
Meio Ambiente:
Processador: Intel (R) Xeon (R) CPU E5620 @ 2.40GHz
SO: 2.6.35-22-generic # 33-Ubuntu
Sinalizadores do compilador GCC: -O3 -msse4 -DINTEL_SSE4 -Wall -std = c99
Eu acho que deve estar relacionado a caches, mas não consigo encontrar um motivo para os seguintes casos hostis ao cache:
Por que meu programa fica lento ao fazer loop sobre exatamente 8192 elementos?
Como a degradação do desempenho desses dois casos é causada por loops hostis que lêem bytes dispersos no cache, desperdiçando o resto do espaço de uma linha de cache.
Aqui está o meu código:
void memcpy_speed(unsigned long buf_size, unsigned long iters){
struct timeval start, end;
unsigned char * pbuff_1;
unsigned char * pbuff_2;
pbuff_1 = malloc(buf_size);
pbuff_2 = malloc(buf_size);
gettimeofday(&start, NULL);
for(int i = 0; i < iters; ++i){
memcpy(pbuff_2, pbuff_1, buf_size);
}
gettimeofday(&end, NULL);
printf("%5.3f\n", ((buf_size*iters)/(1.024*1.024))/((end.tv_sec - \
start.tv_sec)*1000*1000+(end.tv_usec - start.tv_usec)));
free(pbuff_1);
free(pbuff_2);
}
ATUALIZARConsiderando as sugestões de @usr, @ChrisW e @Leeor, refiz o teste com mais precisão e o gráfico abaixo mostra os resultados. O tamanho do buffer é de 26 KB a 38 KB, e eu testei todos os outros 64B (26 KB, 26 KB + 64B, 26 KB + 128B, ......, 38 KB). Cada teste faz um loop de 100.000 vezes em cerca de 0,15 segundo. O interessante é que a queda não ocorre exatamente no limite de 4KB, mas também sai em 4 * i + 2 KB, com uma amplitude muito menor.
PSO @Leeor ofereceu uma maneira de preencher a gota, adicionando um buffer fictício de 2 KB entrepbuff_1
epbuff_2
. Funciona, mas não tenho certeza da explicação de Leeor.