Sort -uを指定してegrepを使用してファイルから取得した一連の一意の行を作成し、それらをカウントしようとしています。行の約10%(アルファベット[ATCG]から100文字すべて)が重複しています。 2つのファイルがあり、それぞれ約3ギグで、50%は関連性がないため、おそらく3億行になります。
LC_ALL=C grep -E <files> | sort --parallel=24 -u | wc -m
LC_ALL = Cと-xを使用してgrepを高速化する間で、最も遅い部分はソートです。マニュアルページを読んだ結果、-parallel = nになりましたが、実験を行ってもまったく改善は見られませんでした。 topを少し掘り下げたところ、-parallel = 24を使用しても、並べ替えプロセスは一度に1つのプロセッサでしか実行されないことがわかりました。
6つのコアと2つのスレッド/コアを備えた4つのチップがあり、合計48個の論理プロセッサを提供します。/proc/cpuinfoが長すぎるため、lscpuを参照してください。
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 48
On-line CPU(s) list: 0-47
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 4
NUMA node(s): 8
Vendor ID: AuthenticAMD
CPU family: 21
Model: 1
Stepping: 2
CPU MHz: 1400.000
BogoMIPS: 5199.96
何が欠けていますか?プロセスがIOバウンドであっても、とにかく並列処理を見るべきではありませんか?ソートプロセスは、常に実際にオンになっているプロセッサの99%を使用するため、並列化が発生している場合はそれを確認できるはずです。メモリは問題ではありません。私は256 GBで遊ぶことができますが、それ以外は何も使用されていません。
Grepをファイルにパイプし、sortでファイルを読み取ることを発見しました。
LC_ALL=C grep -E <files> > reads.txt ; sort reads.txt -u | wc -m
default, file 1m 50s
--parallel=24, file 1m15s
--parallel=48, file 1m6s
--parallel=1, no file 10m53s
--parallel=2, no file 10m42s
--parallel=4 no file 10m56s
others still running
これらのベンチマークを実行すると、パイプによる入力の並べ替えがまったく並列化されないことが明らかになります。ファイルの読み取りが許可されると、ソートは指示に従って負荷を分割します。
sortは、必要でない限りスレッドを作成しません。小さなファイルの場合、オーバーヘッドが多すぎます。残念ながら、sortはパイプを小さなファイルのように扱います。 24スレッドに十分なデータを供給したい場合は、大きな内部バッファーを使用するようにソートするように指定する必要があります(ソートは、大きなファイルが提示されると自動的に行われます)。これは、アップストリームで改善する必要があるものです(少なくともドキュメントでは)。したがって、次のようなものが必要になります。
(export LC_ALL=C; grep -E <files> | sort -S1G --parallel=24 -u | wc -m)
すべてのプロセスにLC_ALL = Cを設定していることに注意してください。これらのプロセスはすべて、このデータを利用するためです。
ところで、次のようなものでソートスレッドを監視できます。
watch -n.1 ps -C sort -L -o pcpu