Misalkan saya ingin menemukan semua kecocokan dalam file teks terkompresi:
$ gzcat file.txt.gz | pv --rate -i 5 | grep some-pattern
pv --rate
digunakan di sini untuk mengukur throughput pipa. Di komputer saya ini sekitar 420Mb / s (setelah dekompresi).
Sekarang saya mencoba untuk melakukan grep paralel menggunakan GNU parallel.
$ gzcat documents.json.gz | pv --rate -i 5 | parallel --pipe -j4 --round-robin grep some-pattern
Sekarang throughput turun menjadi ~ 260Mb / s. Dan apa yang lebih menarik adalah parallel
proses itu sendiri menggunakan banyak CPU. Lebih dari grep
proses (tetapi kurang dari gzcat
).
EDIT 1 : Saya sudah mencoba berbagai ukuran blok ( --block
), serta nilai -N
/ -L
opsi yang berbeda. Tidak ada yang membantu saya pada saat ini.
Apa yang saya lakukan salah?
sumber
--pipe
tidak efisien? Maksud saya apakah itu semacam masalah mendasar atau lebih spesifik implementasi.--pipe
setiap byte tunggal harus melalui proses tunggal, yang harus melakukan sedikit pemrosesan pada setiap byte. Dengan--pipepart
sebagian besar byte tidak pernah dilihat oleh proses pusat: Mereka diproses oleh pekerjaan yang muncul. Karena cukup banyak baris yang menjadi hambatan dalam--pipe
saya akan menyambut C / C ++ coder yang akan menulis ulang bagian yang kemudian akan dijalankan untuk orang-orang yang memiliki C-compiler di jalur mereka.grep sangat efektif - tidak ada gunanya menjalankannya secara paralel. Dalam perintah Anda hanya dekompresi yang membutuhkan lebih banyak cpu, tetapi ini tidak dapat diparalelkan.
Membagi input secara paralel membutuhkan lebih banyak CPU daripada mendapatkan garis yang cocok dengan grep.
Situasi berubah jika Anda ingin menggunakan bukannya grep sesuatu yang membutuhkan CPU lebih banyak untuk setiap baris - maka paralel akan lebih masuk akal.
Jika Anda ingin mempercepat operasi ini - lihat di mana bottleneck - mungkin itu dekompresi (kemudian bantu gunakan alat dekompresi lain atau cpu yang lebih baik) atau - baca dari disk (kemudian bantu gunakan alat dekompresi lain atau sistem disk yang lebih baik).
Dari pengalaman saya - terkadang lebih baik menggunakan lzma (-2 misalnya) untuk mengompres / mendekompresi file - ini memiliki kompresi yang lebih tinggi daripada gzip sehingga lebih sedikit data yang perlu dibaca dari disk dan kecepatannya sebanding.
sumber
Dekompresi adalah hambatan di sini. Jika dekompresi tidak diparalelkan secara internal, Anda tidak akan mencapainya sendiri. Jika Anda memiliki lebih dari satu pekerjaan seperti itu, maka tentu saja meluncurkannya secara paralel, tetapi saluran pipa Anda sendiri sulit untuk diparalelkan. Memisahkan satu aliran ke aliran paralel hampir tidak pernah sepadan, dan bisa sangat menyakitkan dengan sinkronisasi dan penggabungan. Terkadang Anda hanya harus menerima bahwa banyak core tidak akan membantu setiap tugas yang sedang Anda jalankan.
Secara umum, paralelisasi di shell sebagian besar harus pada tingkat proses independen.
sumber
parallel
. Saya setuju bahwa itu pasti dalam kasus pertama (tanpa paralel), tetapi dalam yang kedua (dengan paralel) hambatan ada di sisi paralel. Ini mengikuti dari pengamatan bahwa throughput turun secara signifikan yang diukur denganpv
. Jika bottleneck dalam dekompresi, throughput tidak akan mengubah apa pun yang Anda tambahkan ke pipeline. Ini definisi intuisi dari throughput, saya kira - hal yang paling membatasi throughput.parallel
dapat ditulis ke pipanya. Dalam hal ini, sebagian besargrep
proses hanya menunggu untuk mendapatkan lebih banyak, sementaraparallel
itu bekerja sepanjang waktu untuk melipatgandakan blok menjadi beberapa pipa (yang merupakan operasi IO tambahan dan bahkan dapat memblokir dekompresi jika buffer penuh). Apakah Anda juga mencoba bermain dengan--block
parameter? Secara default1M
begitu sampai satu grep mendapatkan1M
data, sisanya hampir pasti sudah selesai. Karena itu kita kembali ke fakta bahwa tidak masuk akal untuk memaralelkan ini.-N
/-L
opsi. Sepertinya opsi default sangat dekat dengan optimal lokal yang pernah saya alami :)pv
(dengantime
). Dengan cara ini Anda bisa melihat apakahpv
itu sendiri memperlambatnya. Jika ya, makaparallel
menyalin data ke dalam pipa jelas merupakan tambahan biaya tambahan. Dan bagaimanapun, saya cukup yakin,grep
hampir real-time dalam hal ini, terutama jika polanya adalah string sederhana tanpa banyak mundur. Selain itu,parallel
akan interleave dan mengacaukangrep
output.pv
itu sendiri tidak menyebabkan masalah, terima kasih atas sarannya.