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 distcc, ccache e outros. Recentemente, descobri que se eu copiar todo o meu projeto em uma unidade de RAM e compilar a partir daí, o tempo de compilação será reduzido para 30% do original - apenas 1,5 minutos.
Obviamente, trabalhar a partir da unidade de RAM não é prático. Então, alguém sabe como eu posso forçar o sistema operacional a manter sempre um determinado diretório em cache ? Ainda quero que o diretório seja sincronizado de volta ao disco normalmente, mas também quero sempre uma cópia dos dados na memória. Isso é possível?
EDIT:
Como uma solução possível, pensamos apenas em lançar um daemon que é executado a rsync
cada 10 segundos ou mais para sincronizar a unidade de disco com uma unidade de RAM. Depois, executamos a compilação a partir da unidade de RAM. O rsync
é super rápido, mas isso realmente funciona? Certamente o sistema operacional poderia fazer melhor ....
fonte
time
compilar e compartilhar o resultado conosco? Isso dissiparia algumas controvérsias.make clean && /usr/bin/time -v make
(não use a festa construído notime
comando)time
construída em bash (help time
) tem muito menos detalhes (sem detalhado opção) do que o tempo GNU (man time
) sobre o I / O, trocas de contexto, ...Respostas:
A maneira óbvia de manter um monte de arquivos no cache é acessá-los com frequência. O Linux é muito bom em arbitrar entre troca e armazenamento em cache, então suspeito que a diferença de velocidade observada não se deva ao fato de o sistema operacional não manter as coisas no cache, mas a alguma outra diferença entre o uso de tmpfs e outras tentativas.
Tente observar o que está fazendo IO em cada caso. A ferramenta básica para isso é
iotop
. Outras ferramentas podem ser úteis; veja detalhamento da carga de E / S de disco do Linux, por caminho e / ou processo do sistema de arquivos? , Que programa no Linux pode medir E / S ao longo do tempo? e outros threads na falha do servidor.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.
noatime
opção de montagem. Sua solução tmpfs + rsync nunca lê no disco rígido, portanto, nunca precisa gastar tempo extra escrevendo vezes.sync()
ou porque o kernel libera seus buffers de saída com frequência, as gravações levarão mais tempo para um disco rígido do que para tmpfs.fonte
Por padrão, o Linux 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 de disco são armazenados em cache. O ponto aqui é como fazer uso desse recurso do kernel e parar sua tentativa de substituí-lo.O ponto é mudar 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 pelos programas ativos não deve ser trocada e a escolha entre duas outras é bastante arbitrária. Deseja uma troca rápida de programa ou acesso rápido a arquivos? Uma baixa troca prefere manter os programas na memória (mesmo que não sejam usados por muito tempo) e uma alta troca prefere manter mais cache de disco (trocando programas não utilizados). (a escala de swappiness é de 0 a 100 e o valor padrão é 60)Minha solução para o seu problema é alterar o swappiness para muito alto (90-95 para não dizer 100) e carregar o cache:
Como você imagina, você deve ter memória livre suficiente para armazenar em cache todos os seus arquivos de origem e objetos, bem como o compilador, arquivos de cabeçalhos incluídos, bibliotecas vinculadas, seu IDE e outros programas usados.
fonte
tmpfs
no mesmo caso, também seriam trocados.Forçar o cache não é o caminho certo para fazer isso. Melhor manter as fontes no disco rígido e compilá-las no tmpfs. Muitos sistemas de construção, como qmake e CMake, suportam construções fora da fonte.
fonte
O
inosync
daemon parece que faz exatamente o que você deseja se for sincronizar novamente com um ramdisk. Em vez de sincronizar novamente a cada 10 segundos, ele usa o recurso de inotificação do Linux para sincronizar novamente quando um arquivo é alterado. Eu o encontrei no repositório Debian como oinosync
pacote ou sua fonte está disponível em http://bb.xnull.de/projects/inosync/ .fonte
Parece que isso funciona para mim se eu quiser manter certos arquivos ou todos os arquivos em um determinado diretório no cache.
O vmtouch parece fazer exatamente isso. Exemplo 5, pode haver o que você precisa.
Eu precisava executá-lo como root com
sudo
fonte
Dada a memória suficiente, sua compilação a partir do ramdisk não faz E / S. Isso pode acelerar qualquer coisa que leia ou grave arquivos. A E / S é uma das operações mais lentas. Mesmo se você obtiver tudo em cache antes da compilação, ainda terá as E / Ss para gravação, embora elas tenham um 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 no tempo total de compilação. Isso pode não lhe dar muita vantagem.
Construindo o objeto e os arquivos intermediários na RAM, e não no disco. Fazer construções incrementais pode obter ganhos significativos em construções frequentes. Na maioria dos projetos, faço uma compilação diária limpa e compilações incrementais no meio. Compilações de integração são sempre compiladas, mas tento limitá-las a menos de uma por dia.
Você pode obter algum desempenho usando uma partição ext2 com o atime desativado. Sua fonte deve estar no controle de versão em um sistema de arquivos com diário, como ext3 / 4.
fonte
Como afirmado anteriormente, a maneira óbvia é ler toda a estrutura de diretórios e o conteúdo do arquivo que você deseja que seja armazenado em cache.
Você pode automatizar isso escrevendo um script para monitorar a saída de
vmstat 1
(use qualquer ferramenta equivalente para o seu sistema operacional) e mantenha uma soma do número de blocos gravados e lidos. Depois que a soma ultrapassar o limite de sua escolha, leia todos os arquivos que você deseja armazenar em cache, redefina a soma e continue monitorando a saída vmstat. Para ler rapidamente arquivos: se sua árvore contiver muitos arquivos, evitefind ... -exec cat
; tentefind ... -print0 | xargs -0 cat
um programa personalizado que não execute cat para cada arquivo.O monitoramento de E / S de disco é preferível ao uso de um intervalo fixo, porque ele sinaliza para reler seus dados com mais ou menos frequência, dependendo da carga de E / S de disco.
Eu usei esse método automatizado com êxito em sistemas onde eu precisava que algumas leituras de arquivos de índice fossem sempre rápidas, evitando a E / S do disco rígido. Também usei o strace para fazer uma lista de todos os arquivos que são acessados quando eu faço o logon, para manter tudo quente no cache para logins rápidos.
Esta pode não ser a melhor solução possível, mas me serviu bem.
fonte