OpenCLでImageMagickはどれほど高速化されるか
執筆日時:2014/09/07
はじめに
ハードウェアのOpenCL対応についてはネット上に情報が腐るほどあるが、そのOpenCLが如何に働くかということに関して、特にLinux環境下における情報は少ないので、今回は比較的よく利用されている画像処理プログラムであるところのImageMagickを用い、OpenCLを有効化したときと無効化したときで処理時間にどのような差が見られるかを計測した。
環境
CPU: Phenom x4 945
GPU: Radeon HD 7700 (OC:Core/Memory = 1020MHz/1125MHz)
Memory: DDR2-800 4GB Dual-Chanel
OS: Ubuntu Desktop 12.04 LTS 64bit (Kernel: 3.2.0-51-generic)
Driver: Catalist 14.6 beta
SDK: AMD APP SDK v2.9-1
ImageMagick 6.8.9-7 Q16 x86_64 2014-09-02
最新のハイエンドと比べると大分スペック差はあるが、一応CPUは4コアであり、GPUは前世代のミドルレンジなのでそこそこの性能と言える。
なお、以下の測定は全て通常のデスクトップ環境で行っており、他にブラウザやエディタを起動させた状態で行っているが、高い負荷のかかる処理を同時に走らせることはしていない。
材料
変換にかかる時間を調べるのに用いた画像は、右にまとめた8枚の画像である。いずれも解像度は3840x2160pxのいわゆる4Kサイズであり、より大きい解像度のTIFF画像からこのサイズに縮小した上でJPGに変換したファイルである。
詳しくは記さないが、画像ファイルは概ね2~4MBのファイルサイズである。
方法
OpenCL有効化/無効化の切替は、ImageMagickをソースからコンパイルする際、configureに--enable-openclのオプションを付けるか否かで行っている。もしインストールすると自動的にOpenCLが有効化されるならば、--disable-openclをオプションとして付けてconfigureしたのちmake installすれば、無効化できるはずである。なお、ImageMagickをOpenCL有効化でインストールした際に、実行時エラーが出る場合は、GPUのドライバなどが適切にインストールされていない可能性があるので、それらの再インストールなどを試みること。現在有効なプロファイルについては、# convert --versionなどとすれば表示される。
全ての計測は、同じフォルダに入れてある画像8枚をImageMagickのmogrifyコマンドを用いて変換し、それに要した時間をtimeコマンドで測定して行った。8枚の画像を変換するのを1回の試行とし、この試行を21回繰り返すシェルスクリプトを作成して連続的に測定を行った。この21回の試行のうち、結果として用いるのは最初の1回を除く20回分である (最初の1回を除くのは、省電力機能によりストレージやプロセッサの動作開始時における処理速度が低下することに対する懸念からである)。
ImageMagick: Parallel Execution with OpenCL (ImageMagick公式サイト内)によると、現在OpenCLでアクセラレーションされるフィルターは、
- blur
- charcoal
- contrast
- constrast-stretch
- convolve
- despeckle
- edge
- equalize
- emboss
- function
- gaussian-blur
- grayscale
- modulate
- motion-blur
- negate
- noise
- radial-blur
- resize
- sketch
- unsharp
の20種であるが、今回はこのうち使用頻度の高そうな-resizeと+contrast、加えて-gaussian-blurと-motion-blur、それにおまけ程度で-charcoalの計5種類のフィルタについて計測した。
実際に変換する際のコマンドは以下のとおりである。
time mogrify -resize 1920 -format jpg *.JPG
time mogrify +contrast -format jpg *.JPG
time mogrify -gaussian-blur 10 -format jpg *.JPG
time mogrify -motion-blur 0x10+180 -format jpg *.JPG
time mogrify -charcoal 10 -format jpg *.JPG
計測に用いたシェルスクリプトは以下のとおりである。
#!/bin/bash for i in `seq 1 21` do #time mogrify +contrast -format jpg *.JPG #time mogrify -gaussian-blur 10 -format jpg *.JPG #time mogrify -motion-blur 0x10+180 -format jpg *.JPG time mogrify -resize 1920 -format jpg *.JPG #time mogrify -charcoal 10 -format jpg *.JPG rm *.jpg done
なお、今回の環境ではファイル名の大文字小文字が区別されるので、拡張子を大文字にした元ファイルから、拡張子が小文字の変換後ファイルを作るということが同じフォルダ内で可能であり、上記のようなコマンドを用いているが、大文字と小文字が区別されない環境においては正しく動作しないので気を付ける必要がある。
結果
全ての図表で共通であるが、結果は20回の試行における平均値で示し、エラーバーは標準誤差を表す。凡例の*はt-testによる検定結果がP < 0.05、**の場合はP < 0.01であることを示す。
timeコマンドの出力結果におけるreal、user、sysとは、realが実時間、userとsysはCPUが使われた時間である。時間はCPUのコアごとに記録されるので、今回のように複数コアを持つCPUを用いマルチスレッド対応のプログラムを動作させると、realよりもuserとsysの合計が大きくなることがある (それだけ各コアで分散して処理ができていることになる)。基本的には人間から見て処理にかかった時間であるrealを見ておけばよいが、userやsysの値が小さければそれだけCPUが占有されていないことになるので、他のプログラムを同時に実行しているサーバー環境などではこれらの値も重要になる。
それではまず初めに-resize処理の結果を見てみよう。3840x2160pxの画像を1920x1080pxに縮小しJPG圧縮するのにかかった時間であるが、なんと最初からOpenCL有効時の平均処理時間がOpenCL無効時を上回ってしまっている。ただし、グラフを見ても分かるようにOpenCL使用時の結果はばらつきは大きくなっており、20回の試行におけるrealの最小値はNon-OpenCLが3.38sなのに対してOpenCLが2.543sであり、ベストラップではOpenCLが勝っている。
+contrastの結果も-resizeと同じく、realの平均値がOpenCLよりNon-OpenCLで低いが最小値ではOpenCLが勝る (OpenCL: 3.706s, Non-OpenCL: 4.587s)結果となった。
続いてお待ちかね、-gaussian-blurの結果である。お待ちかね、というのはこのフィルタ (-motion-blurも同様)は使用頻度がそこそこ高くなおかつ処理負荷が高いという特徴をもつためである。結果はとてもキレイなものになった。OpenCLではrealで8.52倍、user+sysで言うと25.4倍の高速化がなされている。
次に-motion-blur、こちらも負荷高めのフィルタである。結果は、realで30.3倍の高速化、user+sysだと48.9倍もの高速化がなされている。
最後に-charcoal。これもCPUだけでは処理に時間がかかるが、OpenCLによりrealで5.8倍、user+sysだと22.5倍の高速化がなされている。
考察
まず言えるのは、確かにImageMagickにおける一部のフィルタはOpenCLによって劇的に高速化されているということである。Intel Core i7 4770K vs AMD Phenom II X4 945 95W (外部サイト)を見ると、Phenom x4 945の性能は最新のデスクトップ用ハイエンドCPUであるところのCore i7 4770Kに対して概ね1/3といったところなので、4770KならCPUによる処理が3倍速いと仮定しても、今回Radeon HD 7700を使ったOpenCLによるアクセラレーションで得られた最大で約30倍 (real)という高速化には敵わない。
ただしこの30倍とかいう数字は、フィルタの種類やオプションで指定している数値、処理する画像、そしてハードウェア構成に依存するので、実際にどれだけ高速化されるかは自身の環境で対象となる画像を変換してみないと分からない。注目すべきなのは、-gaussian-blurと-motion-blurの結果で、Non-OpenCLでかかった時間は-motion-blurが-gaussian-blurの概ね4倍 (real)なのに対し、OpenCLではほぼ変わらないことである。基本的にはより負荷が高まるよう、フィルタのオプションを変化させれば、OpenCL有効時と無効時の差は広げることができるはずである。もちろん、性能の低いCPUに強力なGPUを組み合わせることでも差は広がる。
次に-resizeや+contrastでOpenCLによる高速化があまり見られない (どころか、平均値では遅くなっている)点についてであるが、これはOpenCL税とでも言うべきものの影響ではないかと思う。つまりCPUからGPUに仕事を投げる際、またGPUからCPUに結果を返す際、にかかる時間である。問題なのは、この時間が試行ごとにばらつきが大きい点である。-resizeと+contrast以外のグラフでは目立たなくなっているが、OpenCL有効時の結果はどれもばらつきが大きい。今回の測定がデスクトップ環境で行われており、GPUが常に描画を行っているためなのかどうかは分からないが、少なくとも連続して行っている20回の試行の中で、処理時間の増減が起こっているタイミングに明確な傾向は見られない。
この-resizeや+contrastの結果からすると、比較的負荷の低い処理に関しては、OpenCLを使っても十分に体感できるような高速化がなされない場合もあることが分かる。ImageMagickではCPU処理のマルチスレッド化も進んでおり、フィルタの種類にもよるが、topコマンドで確認すれば4コア使用時で350%程度までは普通に出るので、マルチコアを有効活用できる。そういった状態であれば、わざわざOpenCLを有効にせずとも、あるいはGPU等を追加せずとも良いということになる (ただし今回は計測していないが、消費電力等の面でOpenCLの利用が有利に働く可能性もある)。
加えて記しておかなければならないが、OpenCL有効時と無効時でそれぞれ出力された画像の差分を取ると、同一の画像になっていないことが分かる。どうやらフィルタの種類によって差分の大きさにも違いがありそうなのであるが、その点については計測が不十分なので、今回の結果には含めない。いずれ改めて書きたいと思う。
Linux環境におけるOpenCLの利用に関してこれまで多く取り上げられてきたのは、いわゆるパスワードクラックの分野かあるいは3DCGのレンダラ程度であり、マルチメディア変換の分野においてはWindowsやMacに比べて開発や情報が遅れているのが現状である。ImageMagickのOpenCL有効化は何年も前になされているはずなのであるが、現在でも日本語ページはおろか、英語においてもImageMagickでOpenCLを使う方法について詳しく書いたページは見つけにくく、フォーラムなどから少しずつ情報を拾う感じである。今回、Linux環境下で比較的よく用いられるプログラムであるImageMagickを使い、OpenCLの利点を示せたことはよかったと思う。私は基本的にAMD製品を買うことが多いので、今回もAMDのRadeonを用いたOpenCLの利用になったが、今後機会があればGeForceやIntel CPUに内臓のOpenCL対応チップを用いた計測も行っていきたい。