PerlMagick が OpenMP 有効だと高負荷になる件
ImageMagick と PerlMagick を使った CGI が原因不明の高負荷になり、ドツボに嵌ったので、備忘録として残しておくことにします。結論からすると apache + ImageMagick + PerlMagick を安定稼働させるには ImageMagick を OpenMP 無効化してコンパイルする必要があるようです。
具体的には下記のようなオプションを付けてコンパイルを行うことで安定動作となります。
※ --disable-openmp --disable-opencl は一緒に指定する必要があります。
cd /usr/local/src/ wget http://image_magick.veidrodis.com/image_magick/ImageMagick-6.7.4-2.tar.gz tar xvfz ImageMagick-6.7.4-2.tar.gz cd ImageMagick-6.7.4-2 ./configure --disable-openmp --disable-opencl --enable-shared --with-perl make make install
以下検証結果まとめです。
PerlMagick を使った簡単な検証コード
下記のように二枚の画像を構成する簡単なプログラムを検証コードとします。
+ =
#!/usr/bin/perl use Image::Magick; my $img = Image::Magick->new; $img->Read("blankface.gif"); my $img2= Image::Magick->new; $img2->Read("kao.png"); $img->Composite( image => $img2, compose => 'over', x => 0, y => 0 ); my $output = 'composite.png'; $img->Write($output); print "Content-type: image/png\n\n"; open my $fh, '<', $output; binmode $fh; print <$fh>; close $fh;
OpenMP 有効/無効 ImageMagick での apache bench 結果
それぞれ下記のような configure オプションで ImageMagick をコンパイルします。with-perl オプションで PerlMagick も同時にインストールします。
OpenMP 有効
./configure --enable-shared --with-perl && make && make install
OpenMP無効
./configure --disable-openmp --disable-opencl --enable-shared --with-perl && make && make install
configure の出力確認で OpenMP の有効/無効が確認できます。無効時には赤文字は NULL です。
Options used to compile and link: PREFIX = /usr/local EXEC-PREFIX = /usr/local VERSION = 6.7.4 CC = gcc -std=gnu99 -std=gnu99 CFLAGS = -fopenmp -g -O2 -Wall -pthread CPPFLAGS = -I/usr/local/include/ImageMagick PCFLAGS = -fopenmp DEFS = -DHAVE_CONFIG_H LDFLAGS = -L/usr/lib MAGICK_LDFLAGS = -L/usr/local/lib -L/usr/lib LIBS = -lMagickCore -llcms -ltiff -lfreetype -ljpeg -lpng12 -lfontconfig -lXext -lXt -lSM -lICE -lX11 -lbz2 -lxml2 -lz -lm -lgomp -lpthread CXX = g++ CXXFLAGS = -g -O2 -pthread FEATURES = OpenMP
apache bench による性能比較を行います。OpenMP 有効版で試験、OpenMP 無効版で試験した結果を見やすく編集してしています。同時接続数を 10、リクエスト数を 1000 で試験してみました。
ab -n 1000 -c 10 'http://localhost/test/test.cgi'
実行結果比較です。OpenMP 無効化の場合の方が 7.5 倍の性能であることが確認できました。
Concurrency Level: 10 Time taken for tests: 27.19970 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1383442 bytes HTML transferred: 1265000 bytes Requests per second: 37.01 [#/sec] (mean) Time per request: 270.200 [ms] (mean) Time per request: 27.020 [ms] Transfer rate: 50.00 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 8.3 0 142 Processing: 29 268 504.0 146 7907 Waiting: 0 253 480.1 133 7905 Total: 29 268 504.2 147 7907
Concurrency Level: 10 Time taken for tests: 205.12334 seconds Complete requests: 1000 Failed requests: 0 Write errors: 0 Total transferred: 1381132 bytes HTML transferred: 1265000 bytes Requests per second: 4.88 [#/sec] (mean) Time per request: 2050.123 [ms] (mean) Time per request: 205.012 [ms] Transfer rate: 6.58 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 3 40.3 0 689 Processing: 35 2046 1589.5 1553 11708 Waiting: 34 1100 1155.6 734 9594 Total: 35 2049 1592.1 1555 11708
top コマンドによる負荷確認と比較です。OpenMP 無効時の方が CPU 使用率もロードアベレージも低いことが確認できます。
OpenMP無効化
top - 07:40:55 up 9 days, 22:41, 3 users, load average: 5.09, 1.20, 0.43 Tasks: 88 total, 11 running, 77 sleeping, 0 stopped, 0 zombie top - 07:44:16 up 9 days, 22:44, 3 users, load average: 5.08, 1.75, 0.71 Tasks: 88 total, 19 running, 68 sleeping, 0 stopped, 1 zombie Cpu(s): 80.2%us, 19.5%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.3%si, 0.0%st Mem: 510540k total, 354216k used, 156324k free, 25500k buffers Swap: 2048276k total, 15536k used, 2032740k free, 235096k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 14953 apache 17 0 77600 6032 3004 R 2.0 1.2 0:00.06 test.cgi 14915 apache 18 0 0 0 0 R 1.3 0.0 0:00.04 test.cgi 14948 apache 17 0 76640 5108 3000 R 1.3 1.0 0:00.04 test.cgi 14959 apache 17 0 76772 5220 3000 R 1.3 1.0 0:00.04 test.cgi 14960 apache 15 0 0 0 0 Z 1.3 0.0 0:00.04 test.cgi 13947 root 15 0 12724 1056 808 R 0.7 0.2 0:00.11 top 14160 root 15 0 63272 2824 2104 S 0.7 0.6 0:00.15 ab 14887 apache 18 0 23292 2204 1356 R 0.7 0.4 0:00.02 test.cgi 20701 apache 15 0 183m 4216 1240 S 0.7 0.8 0:00.12 httpd 20728 apache 15 0 183m 4216 1240 S 0.7 0.8 0:00.17 httpd 14956 apache 18 0 23292 2224 1356 R 0.3 0.4 0:00.01 test.cgi 14958 apache 17 0 76640 5144 3000 R 0.3 1.0 0:00.01 test.cgi 14961 apache 15 0 76304 3016 1812 R 0.3 0.6 0:00.01 test.cgi 20636 apache 15 0 183m 4216 1240 S 0.3 0.8 0:00.12 httpd 20637 apache 15 0 183m 4216 1240 S 0.3 0.8 0:00.14 httpd 20639 apache 15 0 183m 4224 1248 S 0.3 0.8 0:00.16 httpd 20642 apache 15 0 183m 4216 1240 S 0.3 0.8 0:00.16 httpd
OpenMP有効化
top - 07:50:56 up 9 days, 22:51, 3 users, load average: 13.86, 7.02, 3.02 Tasks: 86 total, 6 running, 75 sleeping, 0 stopped, 5 zombie Cpu(s): 97.7%us, 2.2%sy, 0.0%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.2%si, 0.0%st Mem: 510540k total, 399148k used, 111392k free, 27868k buffers Swap: 2048276k total, 15536k used, 2032740k free, 263652k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 18462 apache 18 0 88376 7624 3936 R 16.0 1.5 0:00.48 test.cgi 18459 apache 17 0 0 0 0 Z 15.0 0.0 0:00.45 test.cgi18446 apache 18 0 0 0 0 Z 10.7 0.0 0:00.32 test.cgi 18450 apache 18 0 0 0 0 Z 10.0 0.0 0:00.30 test.cgi 18452 apache 18 0 0 0 0 Z 10.0 0.0 0:00.30 test.cgi 18455 apache 18 0 88380 7628 3932 S 9.7 1.5 0:00.29 test.cgi 18444 apache 18 0 88376 7624 3932 S 8.7 1.5 0:00.26 test.cgi 18399 apache 19 0 88520 7832 4024 R 6.7 1.5 0:00.54 test.cgi 18458 apache 18 0 88376 7480 3904 S 4.3 1.5 0:00.13 test.cgi 18401 apache 19 0 0 0 0 Z 3.7 0.0 0:00.35 test.cgi 16822 root 15 0 63272 2824 2104 R 0.3 0.6 0:00.17 ab 20643 apache 15 0 183m 4216 1240 S 0.3 0.8 0:00.21 httpd 20703 apache 15 0 183m 4216 1240 S 0.3 0.8 0:00.23 httpd 1 root 15 0 10352 444 408 S 0.0 0.1 0:04.57 init 2 root RT -5 0 0 0 S 0.0 0.0 0:12.33 migration/0 3 root 34 19 0 0 0 S 0.0 0.0 0:00.07 ksoftirqd/0 4 root RT -5 0 0 0 S 0.0 0.0 0:00.03 watchdog/0
上記のような理由で、ImageMagick をソースから単に ./configure && make && make install
でインストールした場合に、PerlMagick を使った CGI を動かすとサーバが高負荷状態になる可能性があります。プログラムとしては問題がないので、一見原因不明の高負荷と見えてしまうのですが、実は ImageMagick のコンパイルオプションでしたって話です。
ちなみに、yum でインストールした場合には、上記のような問題は発生しませんでした。インストールされたバージョンは 6.2.8 でしたが、openmp が無効化(or 6.2.8 はopenmp 未サポート)されていたため安定稼働していました。
yum -y install ImageMagick*
openmp が有効化されているかは convert -version で確認可能です。以下実行結果です。
$ convert -version Version: ImageMagick 6.7.4-2 2011-12-27 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC Features: OpenMP $ convert -version Version: ImageMagick 6.7.4-2 2011-12-27 Q16 http://www.imagemagick.org Copyright: Copyright (C) 1999-2012 ImageMagick Studio LLC Features: $ /usr/bin/convert -version Version: ImageMagick 6.2.8 10/20/10 Q16 file:/usr/share/ImageMagick-6.2.8/doc/index.html Copyright: Copyright (C) 1999-2006 ImageMagick Studio LLC
参考情報
・ ImageMagickとマルチスレッドは混ぜるなキケン!? - shimada-kの日記:
・ 組み込みマルチコア進化論(5):マルチコアにおける標準表記OpenMP (1/3) - @IT MONOist:
コメントやシェアをお願いします!