⚠️ 这是一个非官方翻译网站,与 ImageMagick Studio LLC 无关。准确信息请参阅原文(https://imagemagick.org/openmp/)

并行执行(OpenMP)

ImageMagick 的许多内部算法都进行了线程化,以利用多核处理器芯片和 OpenMP 提供的加速。OpenMP 是用于并行编程的 API 规范。如果你的编译器支持 OpenMP(例如 gcc、Visual Studio 2005)指令,ImageMagick 会自动包含相应支持。要验证这一点,请用以下命令查看 ImageMagick 的 OpenMP 特性:

$ magick identify -version
Version: ImageMagick 7.0.10-50 2021-01-04 Q16 https://imagemagick.org
Copyright: © 1999-2021 ImageMagick Studio LLC
Features: OpenMP(4.5)

启用 OpenMP 后,大多数 ImageMagick 算法会在系统的所有核心上并行执行。ImageMagick 通常会划分工作,使每个线程处理 64 行像素。当各行处理完成后,OpenMP 会继续为每个线程分配更多的像素行块,直到算法完成。例如,如果你拥有一个四核系统并尝试调整图像尺寸,那么调整会在 4 个核心上进行(如果启用了超线程则为 8 个)。

通过使用 tcmalloc 内存分配库减少锁竞争,你可以进一步提升性能。要启用它,请在构建 ImageMagick 时向 configure 命令行添加 --with-tcmalloc。

并行执行的陷阱

在并行环境中预测行为可能很困难。性能可能取决于诸多因素,包括编译器、OpenMP 库的版本、处理器类型、核心数量、内存大小、是否启用超线程、与 ImageMagick 同时执行的应用程序组合,或你所使用的特定图像处理算法。就线程数量而言,确定最优性能的唯一可靠方法就是进行基准测试。ImageMagick 在对命令进行基准测试时包含渐进式线程化,并返回一个或多个线程的耗时和效率。这可以帮助你确定在你的环境中多少个线程最为高效。下面是线程 1–8 的基准测试示例:

$ magick -bench 40 model.png -sharpen 0x1 null:
Performance[1]: 40i 0.712ips 1.000e 14.000u 0:14.040
Performance[2]: 40i 1.362ips 0.657e 14.550u 0:07.340
Performance[3]: 40i 2.033ips 0.741e 14.530u 0:04.920
Performance[4]: 40i 2.667ips 0.789e 14.590u 0:03.750
Performance[5]: 40i 3.236ips 0.820e 14.970u 0:03.090
Performance[6]: 40i 3.802ips 0.842e 15.280u 0:02.630
Performance[7]: 40i 4.274ips 0.857e 15.540u 0:02.340
Performance[8]: 40i 4.831ips 0.872e 15.680u 0:02.070

性能越好,IPS(每秒迭代次数)的值越高。在这个示例中,8 个核心为最优。不过在某些情况下,将线程数设为 1(例如 -limit thread 1)或完全禁用 OpenMP 可能才是最优选择。要禁用该特性,请在 configure 脚本的命令行中添加 --disable-openmp,然后重新构建并重新安装 ImageMagick。