GraphicsMagick在多執行緒環境工作時其自身多執行緒處理會變成單執行緒
修改編譯引數進行測試
./configure --enable-openmp-slow --enable-shared
改為動態載入庫後容易出現的問題:
sudo mv /usr/local/lib/libpng12.so.0 /usr/local/lib/libpng12.so.0.bak
sudo ln -s /usr/lib64/libpng12.so.0 /usr/local/lib/libpng12.so.0
修改GM使用的執行緒數的設定:
export OMP_NUM_THREADS=8
OMP_NUM_THREADS數
實時生成執行緒數
cpu佔用
load_mem時間
default
12
225.3%
50ms
default
24
215.2%
112ms
default
36
227.0%
164ms
伺服器配置:16核
名詞:
GM的C core: C language API for the lowest-level core programming interface
GM的C++API: Magick++ provides an abstract object-oriented C++ interface.
使用兩套API測試的原因是因為GM本身自帶的程式gm是使用C core的api,其執行時候的CPU利用率和處理速度與現在C++API有所不同。
壓力測試分為GM自帶命令列多執行緒測試和使用GM的api多執行緒測試以及不同版本的GM測試。
自帶命令列多執行緒測試命令:
gm benchmark -iterations 1000 -stepthreads 1 convert -resize 100x100 -quality 90 +profile "*" ./test.jpg ./100x100.jpg
結果:執行緒數自增一,預設最多執行緒使用為系統核數,最多執行緒使用可通過環境變數OMP_NUM_THREADS進行設定。並且隨著執行緒數的增 加 CPU的利用率在提升,最高可到1500%多。
單程序中使用GM庫中C++API處理圖片與使用GM庫的C core的API處理圖片測試:
結果:C++API處理圖片不能發揮GM庫OpenMP的多執行緒的效果,CPU使用最多達到100%。使用自動C core處理圖片可以發揮GM自身多執行緒處理圖片的效果,CPU使用情況隨著執行緒數的增加而增加。
多執行緒中使用GM庫中C++API處理圖片與使用GM庫中C core的API處理圖片測試:
結果:GM 的C++API處理圖片依舊是單執行緒執行,OpenMP的設定不起作用,CPU利用率最多200%。使用GM的C core的API在多執行緒環境中OpenMp多執行緒處理圖片失效表現為單執行緒的情況,CPU利用率最多200%。
實時生成測試:
結果:隨著實時生成中執行緒數的設定變大loadmem的時間在有壓力的情況會增加。
壓力測試用例:
./ab -n100000 -c200 -k
./ab -n100000 -c200 -khttp://192.168.128.15/pic/r/79/ab/a280d338458393fff446ff5088ab_247_310.c1.jpg >> test_result/gm2.log
隨後改變OMP_NUM_THREADS的數目對以上測試結果沒有影響,也就是說GM自身多執行緒處理圖片在多執行緒環境中其實是無效的。
使用多程序測試:
使用的GM的C core API,在多程序環境下處理圖片CPU利用率可以根據環境變數OMP_NUM_THREADS的數目進行設定。OMP_NUM_THREADS是 OpenMP的執行緒數。
該執行緒數決定了GM處理圖片時候使用的執行緒。
GM的版本共測試了兩個分別為1.3.17和1.3.18,兩個版本表現的效果是一樣的。
最終結論:GM圖片處理庫在單程序環境中處理圖片而且使用自身C core的API時才能發揮其“瑞士軍刀”的效果,在多執行緒環境中OpenMp會失效,GM表現的是單執行緒處理圖片。
因此想要提升GM多執行緒處理的速度的話宿主程式是多執行緒的情況是不行的。由於GM自身的侷限以後的優化空間可以是多程序處理圖片。
有關該問題作者的回覆:
On Wed, 8 May 2013, 王利超 wrote:
> hi,all:
> I find GraphicsMagick doesn't work well if the program self is multi thread。The CPU is only 200% (my
> computer is 16 core).
> The C++ API of GraphicsMagick is not working when users program is multi thread,openMP
> in GraphicsMagick is not like paralle process.
>
> My test GraphicsMagick versions are :1.3.18 ,1.3.17 ,1.3.16
> single threads test case is like:
The problem is almost certainly because the JPEG coder has been marked
as not thread safe. Take a look at RegisterJPEGImage() in
magick/jpeg.c.
You could experiment by commenting out the two lines that say
entry->thread_support=False; /* libjpeg is not thread safe */
or change from False to True.
or you could try this non-recommended approach (casts away const) with
existing binaries:
MagickInfo *magick_info=("JPEG",MagickInfo &exception);
magick_info->thread_support=MagickTrue;
MagickInfo *magick_info=("JPG",MagickInfo &exception);
magick_info->thread_support=MagickTrue;
before reading/writing the JPEG files. Please let us know how it
turns out. The JP2, PNG, and TIFF coders are marked the same way.
As far as I am aware, only the JPEG error reporting might not be
thread safe because it uses setjmp()/longjmp() and behavior of these
functions in multi-threaded programs is not well-defined because some
processor context might not be restored, or the processor context
restored might not be correct (for example, the longjmp() might occur
on a different CPU than the original setjmp()). This is highly OS and
CPU dependent.
I do have an idea for how to eliminate use of setjmp()/longjmp() but
it would then depend on POSIX threads features.
Bob
--
Bob Friesenhahn
[email protected], http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/