Força o diretório a estar sempre no cache

34

Eu tenho testado métodos diferentes para melhorar o tempo necessário para compilar todo o meu projeto c ++. Atualmente leva ~ 5 minutos. Eu experimentei com distcc, ccache e outros. Recentemente, descobri que, se eu copia todo o meu projeto em um drive RAM, e então compilo a partir dele, o tempo de compilação é reduzido para 30% do original - apenas 1,5 minutos.

Obviamente, trabalhar a partir da unidade RAM não é prático. Então, alguém sabe de uma maneira que eu posso forçar o sistema operacional a manter sempre um determinado diretório em cache ? Eu ainda quero que o diretório seja sincronizado de volta ao disco como normal, mas eu sempre quero uma cópia dos dados na memória também. Isso é possível?

EDITAR: Como uma possível solução, pensamos em lançar um daemon que execute rsync a cada 10 segundos para sincronizar a unidade de disco com uma unidade RAM. Em seguida, executamos a compilação da unidade RAM. O rsync está brilhando rápido, mas isso realmente funcionaria? Certamente o sistema operacional poderia fazer melhor ....

    
por JaredC 28.01.2011 / 16:10

7 respostas

18

A maneira óbvia de manter um monte de arquivos no cache é acessá-los com frequência. O Linux é muito bom em arbitrar entre swapping e caching, então eu suspeito que a diferença de velocidade que você observa na verdade não é devido ao sistema operacional não manter coisas no cache, mas a alguma outra diferença entre o uso do tmpfs e suas outras tentativas. / p>

Tente observar o que está fazendo IO em cada caso. A ferramenta básica para isso é iotop . Outras ferramentas podem ser úteis; consulte E / S do disco do Linux, por divisão do sistema de arquivos e / ou processo? , Qual programa no Linux pode medir I / O ao longo do tempo? , e outros threads no Server Fault.

Aqui estão algumas hipóteses sobre o que poderia estar acontecendo. Se você fizer medições, mostre-as para que possamos confirmar ou refutar essas hipóteses.

  • Se você tiver os tempos de acesso do arquivo ativados, o sistema operacional poderá desperdiçar um pouco de tempo escrevendo esses tempos de acesso. Os tempos de acesso são inúteis para uma árvore de compilação, portanto, verifique se eles estão desativados com a opção noatime mount. Sua solução tmpfs + rsync nunca a partir do disco rígido, por isso nunca precisa gastar tempo extra escrevendo atimes.
  • Se as gravações forem sincronizando , porque o compilador chama sync() ou porque o kernel frequentemente libera seus buffers de saída, as gravações levarão mais tempo para um disco rígido do que para tmpfs.
por 14.02.2011 / 22:58
8

Linux por padrão usa a RAM como cache de disco. Como demonstração, tente executar time find /some/dir/containing/a/lot/of/files > /dev/null duas vezes, a segunda vez é muito mais rápida, pois todos os inodes do disco são armazenados em cache. O ponto aqui é como usar esse recurso do kernel e parar sua tentativa de substituí-lo.

O objetivo é alterar o swappiness . Vamos considerar três tipos principais de uso de memória: programas ativos, programas inativos e cache de disco. Obviamente, a memória usada por programas ativos não deve ser trocada e a escolha entre dois outros é bem arbitrária. Você gostaria de trocar programas rapidamente ou acessar arquivos rapidamente? Um baixo swappiness prefere manter programas na memória (mesmo se não for usado por muito tempo) e um alto swappiness prefere manter mais cache de disco (trocando programas não utilizados). (escala de permuta é de 0 a 100 e o valor padrão é 60)

Minha solução para o seu problema é mudar o swappiness para muito alto (90-95 para não dizer 100) e para carregar o cache:

echo 95 | sudo tee /proc/sys/vm/swappiness > /dev/null # once after reboot
find /your/source/directory -type f -exec cat {} \; > /dev/null

Como você adivinhou, você deve ter memória livre suficiente para armazenar em cache todos os seus arquivos fonte e objeto, assim como o compilador, arquivos de cabeçalhos incluídos, bibliotecas vinculadas, seu IDE e outros programas usados.

    
por 13.02.2011 / 23:52
6

Forçar cache não é o jeito certo de fazer isso. Melhor manter fontes no disco rígido e compilá-las no tmpfs. Muitos sistemas de compilação, como o qmake e o CMake, suportam compilações fora da fonte.

    
por 28.01.2011 / 17:57
6

O daemon inosync parece que faz exatamente o que você quer se você for rsync para um ramdisk. Em vez de rsyncing a cada 10 segundos ou mais, ele usa o recurso inotify do Linux para rsync quando um arquivo é alterado. Eu o encontrei no repositório Debian como o pacote inosync , ou sua fonte está disponível no link .

    
por 15.02.2011 / 02:43
5

Essa coisa parece funcionar para mim se eu quiser manter certos arquivos ou todos os arquivos em um determinado diretório no cache.

vmtouch parece fazer exatamente a coisa. Exemplo 5, pode haver o que você precisa.

vmtouch -dl /whatever/directory/

Eu precisava executá-lo como root com sudo

    
por 25.10.2014 / 10:40
3

Com memória suficiente, sua build do ramdisk não possui E / S. Isso pode acelerar tudo o que lê ou grava arquivos. E / S é uma das operações mais lentas. Mesmo se você tiver tudo armazenado em cache antes da compilação, ainda terá os I / Os para gravação, embora eles devam ter impacto mínimo.

Você pode obter alguma aceleração pré-carregando todos os arquivos no cache, mas o tempo necessário para isso deve ser incluído nos tempos totais de construção. Isso pode não lhe dar muita vantagem.

Construindo o objeto e os arquivos intermediários na RAM, em vez de no disco. Fazer compilações incrementais pode gerar ganhos significativos em construções frequentes. Na maioria dos projetos, faço uma compilação limpa diária e criações incrementais entre eles. As compilações de integração são sempre construções limpas, mas tento limitá-las a menos de uma por dia.

Você pode ganhar algum desempenho usando uma partição ext2 com o atime desativado. Sua origem deve estar no controle de versão em um sistema de arquivos registrados como ext3 / 4.

    
por 14.02.2011 / 18:44
2

Como dito anteriormente, a maneira óbvia é ler toda a estrutura de diretório e o conteúdo do arquivo que você deseja armazenar em cache.

Você pode automatizar isso escrevendo um script para monitorar a saída de vmstat 1 (use qualquer ferramenta equivalente para o seu SO) e mantenha uma soma do número de blocos gravados e lidos. Quando a soma ultrapassar um limite de sua escolha, leia todos os arquivos que você pretende armazenar em cache, reconfigure a soma e continue monitorando a saída do vmstat. Para ler arquivos rapidamente: se sua árvore contiver muitos arquivos, evite find ... -exec cat , em vez disso, tente find ... -print0 | xargs -0 cat ou um programa personalizado que não execute cat para cada arquivo.

O monitoramento de E / S do disco é preferível a usar um intervalo fixo porque ele sinaliza para reler seus dados com maior ou menor frequência, dependendo da carga de E / S do disco.

Eu usei esse método automatizado com sucesso em sistemas em que precisei de algumas leituras de arquivo de índice para sempre ser rápido, evitando E / S de disco rígido. Eu também usei strace para fazer uma lista de todos os arquivos que são acessados quando eu logar, para que eu possa manter tudo em cache para logons rápidos.

Esta pode não ser a melhor solução possível, mas me serviu bem.

    
por 17.08.2011 / 01:13