【问题标题】:Multiple image operations in a single process with gm4java使用 gm4java 在单个进程中进行多个图像操作
【发布时间】:2014-05-24 14:33:58
【问题描述】:

这个问题是关于使用 gm4java 库与 Graphics Magick(在 Scala 中)进行交互的。

我一直在测试 PooledGMService,因为它在 scala 中演示了 here,并且运行良好。

但是,我注意到它在 gm (gm batch batchfile.gm) 的命令行界面中的执行方式与批处理模式不同。当我从命令行运行带有任意数量图像的 gm 批处理文件时,它会启动 1 gm 进程。但是,如果我:

val config = new GMConnectionPoolConfig()
val service = new PooledGMService(config)

然后跨 4 个线程共享服务实例,我在每个线程上对一个图像执行一些操作,例如:

service.execute(
    "convert",
    srcPath.toString(),
    "-resize", percent + "%",
    outPath.toString()
)

我看到创建了 4 个单独的 gm 进程。

我认为这会对性能产生影响(使用 100 张图像进行测试,使用上面提到的代码与带有批处理文件的 gm cli 进行测试,需要相同的时间,但我的 scala 代码使用的 CPU 是原来的 4 倍)。

我的问题是:我如何使用 gm4java 以便单个 gm 进程处理多个图像(或至少对同一图像进行多种转换),就像 cli 批处理模式一样?我用no luck here 尝试了一些尝试(有些非常愚蠢)。

我的确切 scala 代码,可以是 found here if you are curious

2014 年 5 月 27 日更新

comment by gm4java's author 的指导下,我意识到我正在对两个不同的 gm 命令进行基准测试。更新后的基准测试结果是:

100 x 30MB images (3.09GB tot)
on i7 quadcore (8 logical cpu's w/ hyper-threading)

Criteria            Time
gm cli batchfile    106s
my code 1 thread    112s
my code 4 threads   40s
my code 6 threads   31s
my code 7 threads   31s
my code 8 threads   28s

经过仔细检查,我还发现,当我的代码运行时,具有相同进程 ID 的相同 gm 进程始终保持运行。这减轻了我对由于启动和终止 gm 线程相关的一些开销而导致性能下降的担忧。

改写

我想我的问题的核心是如何使 gm4java 尽可能快? tip about matching gm the threadcount with the machine's execution engine count 很有用。还有什么想到的吗?

我的特定用例是将输入图像的大小(平均 30MB,偶尔 50-60MB,很少 100-500MB)调整为几个设置大小(缩略图是最重要和最高优先级)。部署可能会在 amazon ec2 上使用 7 或 14 个“计算单元”

【问题讨论】:

    标签: java scala graphicsmagick


    【解决方案1】:

    PooledGMService 的设计是通过启动多个 GM 进程实例以高度并发的方式处理您的图像处理请求,从而最大限度地利用您的计算机能力。 100 张图片的样本量太小,无法测试性能。如果您的目标是充分利用多 CPU 服务器来转换图像,则需要使用大量样本(至少数千个)进行测试并调整配置以找到要使用的最佳并发 GM 进程数。有关所有配置选项,请参阅 GMConnectionPoolConfig 的文档。

    如果您只有 8 个 CPU,请不要启动超过 7 个 GM 进程。如果您在 2-CPU 笔记本电脑上进行测试,请不要运行超过 2 个 GM 进程。在示例中,您接受了所有默认配置设置,这将根据需要启动最多 8 个 GM 进程。但这不是仅在只有 2 个 CPU 的笔记本电脑上处理 100 个图像的正确配置。

    如果您只想模仿命令行批处理模式。比SimpleGMService 是你最好的朋友。看看here的使用模式。

    正确的解决方案在很大程度上取决于您的实际用例。如果您能告诉我们更多您想要实现的目标、您的硬件环境等,我们可以更好地为您提供帮助。

    【讨论】:

    • 感谢您的快速回复!我已经用用例的细节更新了我的问题。如果您有更多关于加速技巧的提示,请告诉我!据我所知,在重新考虑了我的应用程序中发生的事情之后,PooledGMService 仍然最适合我的需求。如果我要实例化几个 SimpleGMService 连接,我想我只会把管理进程池的责任推给我自己,而不是你的优化库!
    • 使用“缩放”可以为缩略图提供更好的性能,但对于较大尺寸的图像,图像质量可能不如“转换”。要使用的 GM 进程的数量取决于 CPU 和 I/O。从 CPU:GM 1:1 比率开始,如果您的 I/O 很慢并且您看到 CPU 没有完全占用,请增加 GM 进程以充分利用您的 CPU。您还需要注意内存使用情况以避免交换。如果您正在优化吞吐量,您还应该禁用 GM 多线程(选项:-limit thread 1)。
    • 谢谢,我很快会在生产机器上做一些测试,尝试多个 SimpleGMService 实例,以及多个具有“限制线程 1”选项的 PooledGMService 实例,并将它们与具有多线程的 PooledGMService 进行比较。
    • @Ilya,您不需要多个 SimpleGMService 实例,您可以从同一个 SimpleGMService 获得多个连接。每个连接可以执行多个 GM 命令。顺便说一句,我对“限制线程 1”的评论应该添加到发送给 GM 的每个命令中。 GM 总是使用单线程来处理“缩放”命令。它将使用多个线程来处理“转换”命令。如果您只使用单个 GM 流程,这很好。但是,如果您的所有 CPU 都忙于处理具有多个 GM 进程的其他图像,则允许 GM 使用多个线程将增加开销并降低整体吞吐量。
    猜你喜欢
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 2012-11-13
    相关资源
    最近更新 更多