Acesso lento ao disco

1. Acesso lento ao disco

Tiago de Almeida
the_almeida

(usa Sabayon)

Enviado em 04/05/2011 - 11:19h

Olá pessoal!

Estou desenvolvendo um programa em C (em ambiente Linux) que, na sua inicialização, executa um restore de um backup de informações.
Para validação das informações lidas, acesso um arquivo muito grande, onde estão os meus dados, e verifico se cada um deles possui o padrao esperado.
Esse acesso ao disco (ao arquivo grande) acontece em milhões de leituras de 32 bytes em posições aleatórias, não lineares.
Dentro do arquivo que estou lendo, tenho dados que me interessam, que variam o seu tamanho de poucos KB até alguns GB. Cada dado possui cabeçalho e calda, como um pacote. Esses cabeçalhos e caldas, de 32 bytes cada, que estou lendo nesse trecho de código.
Acontece que essa leitura está extremamente lenta, de maneira a impossibilitar o uso dessa estratégia no programa.
Acredito que as posições aleatórias dos dados no disco devem ter grande influência nesse baixo desempenho.
Usando um programa simples que mede a taxa de IO no disco, pude perceber que o programa acessa o disco a apenas 1,5MB/s, em média. No final da execução do loop de leitura, ele parece aumentar a taxa para até 10MB/s, o que ainda não compreendi o porquê.
Estou usando um HD sATA, mas as taxas estão baixas mesmo para um IDE.

Para executar as leituras, já tentei estratégias do tipo (simplificando):

// Posicionamento no offset desejado com lseek, leitura com read, comparação com os dados esperados com memcmp
for(;;){
lseek(offset);
read(buffer);
!memcmp(buffer, esperado);
}

// Mapeamento do arquivo inteiro em memória, comparacao diretamente do offset do arquivo, com os dados esperados
arq_ptr = mmap(arquivo)
for(;;){
!memcmp(arq_ptr + offset, esperado);
}
munmap(arquivo)

// Mapeamento de cada porcao do arquivo desejado em cada iteracao, e comparacao com os dados esperados.
for(;;){
arq_ptr = mmap(arquivo, offset);
!memcmp(arq_ptr, esperado);
munmap(arquivo);
}

Todas as estratégias demonstraram o mesmo desempenho, a mesma taxa de acesso ao disco. Mesmo a estratégia de mapeamento do arquivo em memória que, pelo que entendo, deveria ser mais rápida.
Ou seja, meu gargalo está realmente no acesso ao disco, e não nas funções ou chamadas de sistema utilizadas.

Nos meus testes tomei o cuidado de reiniciar o computador antes de cada execução, para esvaziar as caches e RAM, pois após a primeira execução do programa, o mesmo executa mais de 600 vezes mais rápido, devidos às caches e etc.

Também tentei usar a função madvise para indicar ao kernel a natureza aleatória dos dados nessa região de memória (no caso do arquivo mapeado), para que o read ahead não se tornasse um problema. Porém, isso também não surtiu efeito.

Não sei se preciso mudar alguma coisa na minha implementação, ou se realmente não há modo de acessar tantas posições randômicas de forma mais rápida.

Algum de vocês já teve um problema parecido? Conhece alguma alternativa para a situação?

Obrigado!


  


2. Re: Acesso lento ao disco

Mauricio Souza Klein
Hebang

(usa Arch Linux)

Enviado em 04/05/2011 - 12:13h

Olá!

Talvez seja pesado para o sistema manipular um único arquivo gigantesco.

Uma idéia seria ordenar o arquivo pelo campo de seu interesse e dividi-lo em arquivos menores. Isso pode ser feito usando os comandos sort e split do Linux.

Além de deixar a leitura mais rápida, uma vez que os arquivos são menores, a busca pelo dado pode se tornar mais eficiente, se dividir por faixas os arquivos (por exemplo: arquivo 1 vai de "a" a "d"; o 2 de "e" a "h" e assim por diante).

Espero ter ajudado!


3. Re: Acesso lento ao disco

Ricardo Lino Olonca
ricardoolonca

(usa Debian)

Enviado em 04/05/2011 - 14:56h

Já usou o hdparm para testar o desempenho do teu disco?






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts