文系プログラマによるTIPSブログ

文系プログラマ脳の私が開発現場で学んだ事やプログラミングのTIPSをまとめています。

ImageMagickのOpenMPは並列実行で悪影響するのは本当だった

物凄いload averageになるので注意が必要です。


f:id:treeapps:20180424102046p:plain

ImageMagickをOpenMPオプション有効でインストールした際に、マルチスレッド実行時に異常な高負荷になる、という話が昔から話題になっています。

最近AWTの画像変換をImageMagickで高速化する要件がありました。

この噂が本当なのか、真偽を確かめる機会だったので試してみました。結果、

本当に異常な高負荷になりました

OpenMPでどれくらい高負荷になるか

私が実際試してみた結果は以下の通りです。サーバスペックは、CPU Xeon2.6G(8コア)、Mem4G、です。

スレッド数 CPU load average
2スレッド 100% 20以上
4スレッド 100% 30以上
8スレッド 100% 40以上
12スレッド 100% 50以上

2スレッドでCPU100%です。あり得ません。やはりOpenMPは無効にするしかないですね。

しかしこのOpenMP、コンパイルオプションでしか無効にできないのです。

つまりコンパイルし直しです。しかしImageMagickは50近い依存があり、中々大変な作業です。

お手軽にOpenMPを無効にする

大分怪しいですが以下の方法をとりました。

  1. yum install ImageMagick で最新版をインストールする。
  2. 最新版のソースをwget、OpenMP無効でコンパイル、インストール(上書き)。

これで一応convertコマンドは問題無く動作しています。最初のyumで先に依存ライブラリを収集しておいて、後からOpenMP無効でインストールし直すわけです。1と2のバージョンを一致させれば、基本的に問題は無い(はず)です。

そもそもOpenMPとは何なのか

OpenMPは、並列コンピューティング環境を利用するために用いられる標準化された基盤。OpenMPは主に共有メモリ型並列計算機で用いられる。
MPIでは明示的にメッセージの交換をプログラム中に記述しなければならないが、OpenMPはOpenMPが使用できない環境では無視されるディレクティブを挿入することによって並列化を行う。このため並列環境と非並列環境でほぼ同一のソースコードを使用できるという利点がある。

http://ja.wikipedia.org/wiki/OpenMP

簡単に言うと、汎用化され、簡潔に並列化するための仕組みです。ImageMagick内でOpenMPの使い方が誤っていて、リソースを消費してしまっているのでしょう。多重ループして同じ処理しまくっているとか。

ImageMagickの高速化

  1. convertコマンドは並列化処理する。bashで「convert 〜ほげほげ〜 &」でバックグラウンド実行でもいい。
  2. ImageMagickはOpenMPを無効にする。v6.8時点では絶対に無効にして下さい。
  3. convertコマンドにjpegサイズヒントを付与してメモリ確保を最小限に。convert -define jpeg:size=800x600
  4. convertコマンドにthumbnailオプションを付与してexif情報を削除。convert -thumbnail
  5. convertコマンドのqualityはなるべく小さい値にして画質を落とす。convert -quality 60

ImageMagick逆引きコマンドリファレンス

ImageMagick逆引きコマンドリファレンス