You are currently browsing Eduardo Habkost's articles.

Palavras-chave: linux, cache, buffers, limpeza, memória, carregamento, disco, filesystem

O Linux mantém em memória os dados recentemente carregados do disco, e ali eles ficam enquanto possível. Isso acelera o processo de carregamento destes mesmos dados no futuro, como na execução de programas e leitura de arquivos.

As áreas na memória que carregam esses dados chamam-se caches. Você pode notar os caches em ação quando roda um programa pela segunda vez e ele carrega muito mais rapidamente que na primeira.

Mas às vezes é necessário fazer algum teste onde esse efeito de cache deve ser anulado, por exemplo, medir tempo de carregamento de um programa, ou o tempo necessário para processar algum arquivo. Já vi gente reiniciando a máquina só para poder ter uma medição confiável no tempo de carregamento de um programa.

Para economizar nosso tempo e paciência, e ter um efeito semelhante sem precisar reiniciar a máquina, podemos pedir ao kernel que limpe todos os caches que estiverem em memória. Basta usar uma entrada no /proc, existente nas versões mais recentes do kernel, rodando o comando:

echo 1 > /proc/sys/vm/drop_caches

Palavras-chave: C, memória, cache, performance, velocidade

Todo processador hoje em dia possui memória cache, que ajuda a melhorar a performance, armazenando os dados mais recentemente acessados, para acesso mais rápido pelo processador.

O que nós freqüentemente ignoramos é que a organização dos dados e o padrão de acesso à memória podem aproveitar muito bem ou simplesmente estragar a ajuda que a cache nos dá.

Vamos comparar duas versões de um programa que soma os elementos de uma matriz, e seus tempos de execução:

/* matriz1 */
#define N 10000
#define M 15000

static int m[N][M];

int main()
{
    int i, j, soma = 0;
    for (j = 0; j < M; j++) /* coluna a coluna */
        for (i = 0; i < N; i++)
            soma += m[i][j];
    return 0;
}
/* matriz2 */
#define N 10000
#define M 15000

static int m[N][M];

int main()
{
    int i, j, soma = 0;
    for (i = 0; i < N; i++) /* linha a linha */
        for (j = 0; j < M; j++)
            soma += m[i][j];
    return 0;
}
$ time -p ./matriz1
real 1.44
user 1.38
sys 0.05
$ time -p ./matriz2
real 0.78
user 0.72
sys 0.05

Conseguimos quase cortar pela metade o tempo de execução (de 1,38 para 0,72 segundos), apenas modificando a ordem em que os elementos da matriz são acessados. No segundo caso, os dados são acessados linha a linha (seqüencialmente na memória), aproveitando que blocos de memória contendo elementos vizinhos já foram carregados na memória cache.

Add to Technorati Favorites

Assuntos