Ho 1000000 file da 4-20 kb in una directory (puoi generare file simili come questo:seq 10000 | gzip > a; seq 1000000 | parallel --bar 'head -c{=$_=int(rand()*16)+4=}k a > {}'
)
. Devo copiare quella directory. Ma sembra che devo fare una ricerca per ogni file, quindi ci vuole un po' di tempo.
C'è un modo per velocizzarlo?
Attualmente sto pensando che se potessi ottenere i blocchi del disco occupati da questi file, potrei ordinarli, unire i blocchi che erano vicini (dato che la lettura sequenziale è spesso più veloce della ricerca) e leggere questi blocchi, in modo che fossero nella RAM cache (ho 32 GB di RAM) prima di eseguire la copia.
Ma per farlo funzionare ho bisogno di un modo per identificare su quali blocchi si trovano i file.
Sto usando EXT4 su un dispositivo magnetico (cioè non SSD).
Modifica:
Dovrebbe funzionare ma non funziona:
ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 |
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'
Durante il test su un file di grandi dimensioni, il file non viene memorizzato nella cache.
Modifica2:
Ecco alcuni benchmark. La cache è stata svuotata (echo 3 >/proc/sys/vm/drop_caches
) tra ogni corsa. Misurazioni eseguite con iostats -dkx 5
.
rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s
Quindi cosa possiamo imparare da questo?
Sembra che l'ordinamento per inode sia una buona idea. Ma sembra parallelizzare più cp
aumenta ulteriormente le prestazioni. Vale la pena sottolineare che il sorgente foo/
è un disco magnetico, quindi questo attacca il mito secondo cui parallelizzare l'I/O su un singolo mandrino non accelererà l'I/O:parallelizzare in modo chiaro e coerente accelera la copia qui.
Risposta accettata:
Ammesso che
- voci restituite da
readdir
non sono ordinati per numero di inode - leggere i file in ordine di inode riduce il numero di operazioni di ricerca
- il contenuto della maggior parte dei file è nell'allocazione iniziale di 8k (un'ottimizzazione ext4) che dovrebbe anche produrre meno operazioni di ricerca
puoi provare a velocizzare la copia copiando i file in ordine di inode.
Ciò significa usare qualcosa del genere:
$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist