Escrever na subpasta é mais rápido do que escrever na pasta pai

Escrever na subpasta é mais rápido do que escrever na pasta pai

Eu uso dd para medir o desempenho de gravação e observei algo estranho: escrever em/data/emzed2 é mais rápido do que escrever em/data. Foi assim que medi o desempenho:

$ dd se=/dev/zerode=/data/emzed2/testfilebs=32

^C4921834+0 registros em

4921834+0 registra 157498688 bytes (157 MB) copiados, 2.87329 s,54,8MB/s

$ dd se=/dev/zerode =/dados/arquivo de testebs=32

^C2487991+0 registros em

2487991+0 registra 79615712 bytes (80 MB) copiados, 2.6501 s,30,0MB/s

ambas as pastas estão na mesma partição em uma unidade SSD. Eu uso o Ubuntu 14.04 e repeti a experiência várias vezes com resultados semelhantes.

Alguma idéia do que está acontecendo ?

Responder1

Parece que você foi atingido por otimizações ext4. Algumas delas são descritas emLayout de disco Ext4documentação.

Cada vez que você aumenta um arquivo, por exemplo com dd, algum lugar é alocado para os novos dados. Eventualmente, o arquivo poderia ser fragmentado, ou seja, os dados poderiam ser espalhados em vários pedaços pelo disco. A fragmentação é uma fonte bem conhecida de lentidão (ao ler e escrever) e, portanto, as implementações de sistemas de arquivos geralmente tentam evitá-la. A fragmentação é muito mais cara com discos giratórios (a cabeça precisa viajar para pedaços sucessivos) do que com SSD, mas a maioria das implementações de sistemas de arquivos usa estratégias otimizadas de disco giratório com SSD.

Uma combinação do terceiro, quarto e quinto "truques" descritos na documentação mencionada acimapoderexplique por que escrever no subdiretório é mais rápido no seu caso.

O quinto truque é que o volume do disco seja dividido em grupos de blocos de 128 MB. […] Quando um diretório é criado no diretório raiz, o alocador de inode verifica os grupos de blocos e coloca esse diretório no grupo de blocos menos carregado que pode encontrar.

Como resultado, emzed2provavelmente foi criado um bloco vazio de 128 MB.

O quarto truque é que todos os inodes em um diretório sejam colocados no mesmo grupo de blocos do diretório, quando possível.

Conseqüentemente, /data/testfileé criado em um grupo de blocos raiz (provavelmente muito carregado), enquanto /data/emzed2/testfileé criado em um grupo de blocos (provavelmente vazio) emzed2.

O terceiro truque […] é que ele tenta manter os blocos de dados de um arquivo no mesmo grupo de blocos que seu inode.

Para /data/emzed2/testfile, o sistema de arquivos primeiro alocará todos os blocos de dados no emzed2grupo de blocos. Se este bloco estava inicialmente vazio, para os primeiros 128 MB, isso significa que não há fragmentação alguma. Para /data/testfile, o sistema de arquivos primeiro preencherá o grupo de blocos raiz, se ainda não tiver sido preenchido, e então procurará outros locais para armazenar dados.

Além disso, você está aumentando o arquivo em 32 bytes por vez. Felizmente, sistemas de arquivos como o ext4 alocam mais dados do que você solicita (em pedaços de 8kb no caso do ext4) e tentam atrasar a alocação. Você provavelmente veria um padrão semelhante com bs=8196, mas a diferença de velocidade pode diminuir com tamanhos de bloco maiores.

informação relacionada