A gravação na subpasta é mais rápida do que gravar no pai

6

Eu uso dd para medir a performance de gravação e observei algo estranho: escrever para / data / emzed2 é mais rápido do que gravar em / data. Esta é a maneira que eu medi o desempenho:

$ dd if=/dev/zero of=/data/emzed2/testfile bs=32

^C4921834+0 records in

4921834+0 records out 157498688 bytes (157 MB) copied, 2,87329 s, 54,8 MB/s

$ dd if=/dev/zero of=/data/testfile bs=32

^C2487991+0 records in

2487991+0 records out 79615712 bytes (80 MB) copied, 2,6501 s, 30,0 MB/s

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

Alguma ideia do que está acontecendo?

    
por rocksportrocker 03.07.2014 / 10:18

1 resposta

4

Parece que você é atingido por otimizações do ext4 . Alguns deles são descritos na documentação Layout de Disco Ext4 .

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

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

The fifth trick is that the disk volume is cut up into 128MB block groups. […] When a directory is created in the root directory, the inode allocator scans the block groups and puts that directory into the least heavily loaded block group that it can find.

Como resultado, emzed2 provavelmente foi criado em um bloco vazio de 128 MB.

The fourth trick is that all the inodes in a directory are placed in the same block group as the directory, when feasible.

Consequentemente, /data/testfile é criado no grupo de blocos raiz (provavelmente com carga pesada), enquanto /data/emzed2/testfile é criado no grupo de blocos (provavelmente vazio) emzed2 .

The third trick […] is that it tries to keep a file's data blocks in the same block group as its inode.

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

Além disso, você está crescendo o arquivo 32 bytes por vez. Felizmente, os sistemas de arquivos como o ext4 alocam mais dados do que o que você solicita (por partes 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 poderia diminuir com tamanhos de bloco maiores.

    
por 12.07.2014 / 10:29