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.cn Copyright: © 1999-2021 ImageMagick Studio LLC Features: OpenMP(4.5)
启用 OpenMP 后,大多数 ImageMagick 算法将在系统上的所有核心上并行执行。ImageMagick 通常会将工作分成多个部分,以便每个线程处理 64 行像素。随着行的完成,OpenMP 会将更多像素行块分配给每个线程,直到算法完成。例如,如果您有一个四核系统,并尝试调整图像大小,调整大小将在 4 个核心上进行(如果启用了超线程,则为 8 个核心)。
您可以通过使用 tcmalloc 内存分配库来减少锁争用,从而进一步提高性能。要启用它,请在构建 ImageMagick 时将 --with-tcmalloc 添加到 configure 命令行。
并行执行的风险
在并行环境中预测行为可能很困难。性能可能取决于许多因素,包括编译器、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 可能最优。要禁用此功能,请在您的配置脚本命令行中添加 --disable-openmp,然后重新构建并重新安装 ImageMagick。