マルチコアCPUを活用したファイル圧縮

 デスクトップ・コンピューターに搭載されているCPUのコアは2個から4個、やがては8個へと増加の一途だ。それに応じてソフトウェアが計算量の大きな処理を並列処理する能力の重要性も増している。圧縮関連のツールでは、 mgzip pbzip2 がマルチコアに対応しており、前者は圧縮処理に、後者は圧縮とその復元処理にマルチコアを活用することができる。

 どちらの場合も、圧縮ファイルの復元は、それぞれの標準ツールで可能だ。つまり、pbzip2の圧縮ファイルにはbzip2を、mgzipの圧縮ファイルにはgunzipを使う。Fedora 8の場合、pbzip2のパッケージが標準リポジトリーにあり「yum install pbzip2」でインストール可能。一方、mgzipは、ほとんどのディストリビューションでパッケージがなく、ソースからインストールする必要がある。

 しかも、コンパイルでエラーが発生する。zlibヘッダーにはgz_headerが定義されているが、mgzip.cでも同じ変数が正当なgzipアーカイブの16進値を保持するために使われているからだ。

$ make
gcc  -g -O2   -c -o mgzip.o mgzip.c
mgzip.c:40: error: 'gz_header' redeclared as different kind of symbol
/usr/include/zlib.h:124: error: previous declaration of 'gz_header' was here
mgzip.c: In function 'compress_infile_to_outfile':
mgzip.c:530: warning: cast to pointer from integer of different size

 解決は簡単。gz_header変数にプレフィックスを付け、それに合わせてこの変数への参照を修正すればよい。参照はmgzip.cの中に数カ所にある。プレフィックスは、gz_header以外で適正なCの識別子であれば何でもよい。たとえば、mgzip_gz_headerなどとする。

圧縮および復元機能

 コマンドライン・スイッチは、どちらの場合も、使い慣れた非並列版のものとほぼ同じだ。ただし、並列版にはないオプションがある。たとえば、gzipのスイッチ--recursiveはmgzipにはない。

 pbunzip2の並列処理能力を見ると弱点が1つある。マルチコアを活用して圧縮ファイルを復元できるのはpbzip2で圧縮したファイルの場合だけなのだ。pbzip2はファイルを部分ごとに圧縮し、pbunzip2はその各部分を並列に復元する、このときマルチコアが利用されるからだ。したがって、カーネル・ソースのミラーサイトからダウンロードしたlinux-2.6.23.tar.bz2を復元する場合も1つのコアしか使われないことになる。pbzip2がファイルを分割すると、それによって圧縮ファイルのサイズが増加するが、増加量はごくわずかとされている(pbzip2の説明書によると0.2%)。そこで、本体のbzip2プログラムがファイルを分割するようにしてはいかがだろう。シングルコアの利用者の負担はほとんど変わらず、マルチコアの利用者は大いに助かるはずだ。

 下に両ツールの簡単な使用例を示す。bzip2とgzipの利用者には、いずれもお馴染みのものだろう。この数字でpbzip2による圧縮ファイルのサイズを確認すると、確かに非並列版とほとんど同じ、わずか0.46%大きくなるだけだ。

$ bunzip2 linux-2.6.23.tar.bz2
$ gzip -c  linux-2.6.23.tar > linux-2.6.23.tar.gzip
$ mgzip -c linux-2.6.23.tar > linux-2.6.23.tar.mgzip
$ ls -lh
-rw-r----- 1 ben ben 253M 2008-01-19 18:55 linux-2.6.23.tar
-rw-rw-r-- 1 ben ben  56M 2008-01-19 18:57 linux-2.6.23.tar.gzip
-rw-rw-r-- 1 ben ben  67M 2008-01-19 18:57 linux-2.6.23.tar.mgzip

$ gunzip -c linux-2.6.23.tar.mgzip > linux-2.6.23.tar.mgzip-gunzip
$ md5sum linux-2.6.23.tar.mgzip-gunzip linux-2.6.23.tar
853c87de6fe51e57a0b10eb4dbb12113  linux-2.6.23.tar.mgzip-gunzip
853c87de6fe51e57a0b10eb4dbb12113  linux-2.6.23.tar

$ bzip2  -c -k -9 linux-2.6.23.tar > linux-2.6.23.tar.bzip2
$ pbzip2 -c -k -9 linux-2.6.23.tar > linux-2.6.23.tar.pbzip2

$ ls -lh
-rw-r----- 1 ben ben 253M 2008-01-19 18:55 linux-2.6.23.tar
-rw-rw-r-- 1 ben ben  56M 2008-01-19 18:57 linux-2.6.23.tar.gzip
-rw-rw-r-- 1 ben ben  67M 2008-01-19 18:57 linux-2.6.23.tar.mgzip
-rw-rw-r-- 1 ben ben  44M 2008-01-19 19:03 linux-2.6.23.tar.bzip2
-rw-rw-r-- 1 ben ben  44M 2008-01-19 19:01 linux-2.6.23.tar.pbzip2

$ ls -l
-rw-r----- 1 ben ben 264704000 2008-01-19 18:55 linux-2.6.23.tar
-rw-rw-r-- 1 ben ben  45488158 2008-01-19 19:03 linux-2.6.23.tar.bzip2
-rw-rw-r-- 1 ben ben  57928789 2008-01-19 18:57 linux-2.6.23.tar.gzip
-rw-rw-r-- 1 ben ben  69968799 2008-01-19 18:57 linux-2.6.23.tar.mgzip
-rw-rw-r-- 1 ben ben  45695449 2008-01-19 19:01 linux-2.6.23.tar.pbzip2

 現行のpbzip2にも大きな欠点がある。mgzipは圧縮対象のデータをstdinから読めるためパッケージしたばかりのtarファイルをパイプを介して流し込むことができるが、pbzip2はstdinあるいはパイプを介して入力することができないのだ。したがって、pbzip2でtarファイルを圧縮するには、実体あるファイルとしてtarファイルを作る必要がある。以下に、マルチコアCPU上でpbzip2を使って圧縮したtarballを展開するコマンドと、tarファイルをpbzip2で圧縮するコマンドを示す。

$ pbunzip2 -c  /tmp/test/linux-2.6.23.tar.pbzip2 | tar xvf -

$ tar cvf linux-2.6.23.tar linux-2.6.23
$ pbzip2 -9 linux-2.6.23.tar

$ tar cvO linux-2.6.23 | mgzip > linux-2.6.23.tar.gz

File sizes
圧縮ファイルの大きさ Time to compress 圧縮処理時間 Decompression times 復元処理時間

 この2つの並列版圧縮ツールのパフォーマンスを見るために、ベンチマークを実行した。コンピューターはIntel Q6600 2.4GHzクワッドコアを搭載したマシン、圧縮対象のファイルにはlinux-2.6.23.tarを使った。このファイルを選んだのはどこにもあることと、この記事の読者はソースをパッケージしたtarファイルをよく使い、参考になると考えたからだ。

 圧縮ファイルの大きさと圧縮処理時間をそれぞれのグラフに示した。このグラフから、スイッチを付けないデフォルト状態でのmgzipは、gzipに比べ、処理はかなり速いが、圧縮ファイルのサイズもかなり大きい。スイッチ-9を付けると速度は2倍で、サイズはほぼ同等になった。pbzip2の場合は、スイッチの有無にかかわらず、サイズはほぼ同じ。スイッチ-9を付けた場合、クワッドコアを相当程度活用でき、圧縮時間は31%に短縮された。

 圧縮ファイルの復元処理時間も興味深い。このテストでは、マルチコアでの復元処理ができるように、どちらの場合もpbzip2の出力を使っている。

 mgzipやpbzip2を利用すると、CPUに搭載されているコアをすべて活用し、圧縮とその復元に要する時間を短縮することができる。圧縮されたアーカイブを復元するということは、その次にさらなる作業が控えているはずだから、この時間短縮は明らかに大きなメリットになる。通常のbzip2で圧縮やその復元処理を行えば、Q6600クワッドコア・マシンが持つ4個のコアのうち事実上3個は遊ばせていることになる。また、クーロン・ジョブを仕掛けておき、インターネットからダウンロードしたbzip2ファイルをpbzip2方式に変換しておくのもよかろう。必要になったとき、すべてのコアを使って圧縮ファイルを復元できるからだ。

Ben Martin 10年以上にわたってファイルシステムを研究。博士課程を修了し、現在、libferris、ファイルシステム、検索ソリューションを中心にコンサルティングをしている。

Linux.com 原文