Aumentando o desempenho de leituras de arquivos de texto não criptografado

1

Em nosso aplicativo de bioinformática, temos arquivos grandes (até 900MB, normalmente 100MB). Esses arquivos contêm uma representação em texto claro de um genoma e são essencialmente um arquivo de uma linha com uma sequência de caracteres.

Os dados são referenciados por localização, por exemplo, o cromossomo 7 começa na posição 1 e termina na posição 158937463. Normalmente, extraímos uma pequena seção com cerca de 400 caracteres, por exemplo: da posição 4,120,000 4,120,400.

Temos um utilitário escrito em Ruby para essa finalidade: link e funciona lendo o arquivo de o início.

Fazemos essas leituras várias vezes e elas estão diminuindo nossa aplicação. Eu queria saber quais opções estão disponíveis para o cache? Os dados de origem nunca serão alterados, mas os intervalos serão alterados com frequência. Estamos executando o Ubuntu Server 14 x64 em uma máquina com 128 GB de RAM.

Existe alguma maneira de aumentar o desempenho no nível do sistema operacional? Talvez carregar o arquivo inteiro na memória ou de alguma forma armazenar em cache as solicitações?

EDITAR

Devo adicionar se houver opções como, de alguma forma, atribuir mais memória ao cache de arquivos que ajudaria, os ponteiros seriam bem-vindos. Podemos considerar um servidor dedicado para essas leituras caso precisem ser sintonizadas de uma maneira específica.

EDIT 2 Estamos executando uma CPU Xeon E5-1650 Hexa-Core e SSDs duplos (que podem ser invadidos), juntamente com 128 GB de RAM.

    
por ardochhigh 17.10.2014 / 14:42

2 respostas

1

O kernel do linux faz o gerenciamento de cache automaticamente. Tudo o que é carregado na RAM, fica lá até que outro processo precise de RAM e não haja mais disponível. Então, no kernel do Linux, a RAM deve estar sempre cheia. Seu sistema tem 128 GB de RAM, isso é mais do que suficiente para um arquivo de 100-1000 MB.

Para carregar um arquivo enorme na RAM, apenas cat it:

cat huge_file > /dev/null 2>&1

Toda saída é enviada para /dev/null , mas para isso deve passar a RAM do sistema. Ao fazer isso, você pode observar como Cached em /proc/meminfo aumenta.

Quando cat terminar, execute o aplicativo Ruby. O aplicativo Ruby agora lê a versão em cache do arquivo enorme.

    
por 17.10.2014 / 14:58
1

Use dd para ler uma seção de um arquivo sem ler tudo que o precede. Para o seu exemplo (lendo bytes 4,120,000-4,120,400) você pode usar

dd  bs=400  skip=10300  count=1  if=your_input_file  of=your_output_file

Isso define um tamanho de bloco lógico de 400 bytes, e depois diz dd para pular os primeiros 10300 "blocos lógicos" do arquivo de entrada ( if ). 10300 é 4,120,000 ÷ 400. Em seguida, ele lê um bloco ( count=1 ) de 400 bytes e o grava no arquivo de saída ( of ). Se você omitir a especificação of , dd irá escrever na saída padrão, então você pode canalizar para algo.

Se o ponto de partida (deslocamento) não for garantido para ser um múltiplo inteiro do tamanho do bloco (ou mesmo se for), você pode fazer coisas mais complicadas, como

(dd bs=10000 skip=412 count=0;  dd bs=400 count=1 of=your_output_file) < your_input_file

ou

(dd bs=4120000 skip=1 count=0;  dd bs=400 count=1 of=your_output_file) < your_input_file

onde

  • Novamente, você pode omitir a especificação of e isso será gravado na saída padrão.
  • Se você executar dd sem uma especificação if , ele será lido na entrada padrão. A entrada padrão para todo o grupo de comandos (dd …; dd …) vem do < your_input_file no final.
  • O primeiro comando dd não lê nem grava dados, por causa do count=0 ; só procura.
  • Como os dois comandos dd obtêm sua entrada padrão do mesmo redirecionamento de E / S, a busca feita pelo primeiro irá afetar o ponteiro do arquivo que o segundo vê.
por 18.10.2014 / 01:02