Apenas não use dd
. Por exemplo, use cp
e você receberá o pagecache para gravações.
Depois de ler alguns artigos sobre o cache de páginas VFS do Linux e os parâmetros ajustáveis como dirty_ratio
i estava com a impressão de que o cache de páginas operaria como camada de cache de leitura e gravação.
Mas, usando o teste simples abaixo, ele funciona bem para melhorar a velocidade de leitura dos arquivos localizados no cache de páginas, mas parece não funcionar nas gravações.
por exemplo,
Limpe o cache e grave no arquivo.
# swapoff -a
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/dev/zero of=/home/flo/test bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.182474 s, 172 MB/s
Verifique se o arquivo está na cache da página
# vmtouch /home/flo/test
Files: 1
Directories: 0
Resident Pages: 7680/7680 30M/30M 100%
Elapsed: 0.000673 seconds
Ler do arquivo para confirmar está vindo do cache.
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.00824169 s, 3.8 GB/s
Largue a cache e leia novamente para provar a diferença de velocidade.
# echo 3 > /proc/sys/vm/drop_caches
# dd if=/home/flo/test of=/dev/null bs=1M count=30
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 0.132531 s, 237 MB/s
Como não estou usando DIRECT_IO com dd, esperava que o cache de páginas fosse usado como um tipo de cache de write-back. E com base em dirty_ratio
ou dirty_expire_centiseconds
... eventualmente, os dados seriam confirmados no disco.
Alguém pode explicar como o VFS lida com o processo de leitura e gravação de forma diferente, especialmente durante as gravações e por que não há ganho de velocidade.
Existe alguma maneira de tornar o vfs mais agressivo no cache de gravação para que ele se comporte mais como o cache de write-back que você pode encontrar em um controlador RAID, por exemplo.
Obrigado
fLo
Apenas não use dd
. Por exemplo, use cp
e você receberá o pagecache para gravações.
Para ver o comportamento rápido, tenho que fazer rm test
primeiro. Por exemplo. Eu vejo dd
report 1GB / s em vez de 150MB / s.
Referências:
auto_da_alloc
em man ext4 . Embora as referências apenas expliquem porque pensei em tentar isso, isso não explica realmente porque isso faz com que o OI bloqueie.
No meu computador o bloqueio só pareceu acontecer dentro do novo código WBT ("thrunkling writeback") ... que foi adicionado em 2016, após você fez sua pergunta. Eu não analisei porque isso causaria isso. E foi embora quando o WBT foi desativado.
Minha versão do kernel é 4.18.16-200.fc28.x86_64
.
strace -T
mostra que todo o tempo foi gasto em close (), o que faz mais sentido para mim. Eu tentei usar perf
também. Não funcionou como deveria, mas mostrava traços de pilha como
dd 17068 [003] 475165.381526: sched:sched_switch: dd:17068 [120] T ==> kworker/3:1H:19326 [100]
ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
ffffffffa390c172 __sched_text_start+0x352 ([kernel.kallsyms])
ffffffffa390c6a8 schedule+0x28 ([kernel.kallsyms])
ffffffffa30def32 io_schedule+0x12 ([kernel.kallsyms])
ffffffffa3461ed7 wbt_wait+0x337 ([kernel.kallsyms])
ffffffffa342ee33 blk_queue_bio+0x123 ([kernel.kallsyms])
ffffffffa342d114 generic_make_request+0x1a4 ([kernel.kallsyms])
ffffffffa342d3c5 submit_bio+0x45 ([kernel.kallsyms])
ffffffffa3377d78 ext4_io_submit+0x48 ([kernel.kallsyms])
ffffffffa335da2c ext4_writepages+0x70c ([kernel.kallsyms])
ffffffffa3209311 do_writepages+0x41 ([kernel.kallsyms])
ffffffffa31f808e __filemap_fdatawrite_range+0xbe ([kernel.kallsyms])
ffffffffa334b9ec ext4_release_file+0x6c ([kernel.kallsyms])
ffffffffa32a9d4e __fput+0xae ([kernel.kallsyms])
ffffffffa30cf474 task_work_run+0x84 ([kernel.kallsyms])
ffffffffa3003e6e exit_to_usermode_loop+0xce ([kernel.kallsyms])
ffffffffa300425d do_syscall_64+0x14d ([kernel.kallsyms])
ffffffffa3a00088 entry_SYSCALL_64_after_hwframe+0x44 ([kernel.kallsyms])
7fcca3a60654 __close+0x14 (/usr/lib64/libc-2.27.so)
que me lembrou que eu estava testando o programador de% E / S deadline
, com o WBT ("aceleração de write-backback") ativado. Desabilitar o WBT (inclusive mudando para o CFQ, que é incompatível) me deu o comportamento rápido de novo!
Os comandos perf
que usei para ver isso foram:
sudo perf record -e sched:sched_stat_sleep -e sched:sched_switch -e sched:sched_process_exit -gP -o ~/perf.data dd if=/dev/zero of=test bs=1M count=30
sudo perf script -i ~/perf.data | cat