如何提高读写密集型imagemagick脚本的性能? [英] How do I improve the performance of an read-write intensive imagemagick script?

查看:177
本文介绍了如何提高读写密集型imagemagick脚本的性能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用bash脚本处理一系列图像以进行间隔拍摄电影。该方法称为快门拖动,我正在为所有图像创建移动平均值。以下脚本可以正常工作:

I use a bash script to process a bunch of images for a timelapse movie. The method is called shutter drag, and i am creating a moving average for all images. The following script works fine:

#! /bin/bash
totnum=10000
seqnum=40
skip=1
num=$(((totnum-seqnum)/1))
i=1
j=1
while [ $i -le $num ]; do
    echo $i
    i1=$i
    i2=$((i+1))
    i3=$((i+2))
    i4=$((i+3))
    i5=$((i+4))
    ...
    i37=$((i+36))
    i38=$((i+37))
    i39=$((i+38))
    i40=$((i+39))
    convert $i1.jpg $i2.jpg $i3.jpg $i4.jpg $i5.jpg ... \
            $i37.jpg $i38.jpg $i39.jpg $i40.jpg \
            -evaluate-sequence mean ~/timelapse/Images/Shutterdrag/$j.jpg 
    i=$((i+$skip))
    j=$((j+1))
done

但是,我注意到这个脚本需要很长时间来处理大量平均窗口(每张图像1张)的图像。我想,这是由后台的大量阅读和写作引起的。

However, i noticed that this script takes a very long time to process a lot of images with a large average window (1s per image). I guess, this is caused by a lot of reading and writing in the background.

是否有可能提高此脚本的速度?例如,通过将图像存储在存储器中,并且每次迭代都删除第一个图像,并仅加载最后一个图像。

Is it possible to increase the speed of this script? For example by storing the images in the memory, and with every iteration deleting the first, and loading the last image only.

我发现 mpr :{label} imagemagick的功能,但我想这不是正确的方法,因为在 convert 命令之后内存被清除了?

I discovered the mpr:{label} function of imagemagick, but i guess this is not the right approach, as the memory is cleared after the convert command?

推荐答案

建议1 - RAMdisk

如果你想在开始之前将所有文件放在RAMdisk上,它应该极大地帮助你提高I / O速度。

If you want to put all your files on a RAMdisk before you start, it should help the I/O speed enormously.

所以,要制作一个1GB的RAMdisk,请使用:

So, to make a 1GB RAMdisk, use:

sudo mkdir /RAMdisk
sudo mount -t tmpfs -o size=1024m tmpfs /RAMdisk

建议2 - 使用MPC格式

因此,假设您已完成上一步,请将所有JPEG转换为RAMdisk上的MPC格式文件。 MPC文件可以直接进入内存而无需CPU需要进行昂贵的JPEG解码,因为MPC的格式与 ImageMagick 在内存中使用的格式相同,但是在磁盘上。

So, assuming you have done the previous step, convert all your JPEGs to MPC format files on the RAMdisk. The MPC file can be dma'ed straight into memory without your CPU needing to do costly JPEG decoding as MPC is just the same format as ImageMagick uses in memory, but on-disk.

我会用 GNU Parallel 这样做:

parallel -X mogrify -path /RAMdisk -fmt MPC ::: *.jpg

-X 将尽可能多的文件传递给 mogrify ,而不会产生 convert 流程。 -path 表示输出文件必须到达的位置。 -fmt MPC 使 mogrify 将输入文件转换为 MPC 格式(Magick Pixel Cache)文件,您在循环中的后续转换命令可以通过纯DMA读取而不是昂贵的JPEG解码。

The -X passes as many files as possible to mogrify without creating loads of convert processes. The -path says where the output files must go. The -fmt MPC makes mogrify convert the input files to MPC format (Magick Pixel Cache) files which your subsequent convert commands in the loop can read by pure DMA rather than expensive JPEG decoding.

如果您没有或不喜欢 GNU Parallel ,只需省略前导 parallel -X :::

If you don't have, or don't like, GNU Parallel, just omit the leading parallel -X and the :::.

建议3 - 使用GNU Parallel

你也可以并行运行@chepner的代码...

You could also run @chepner's code in parallel...

for ...; do
   echo convert ...
done | parallel

基本上,我回显所有命令而不是运行它们,然后回显命令列表由 GNU Parallel 运行。如果您不能像Eric建议的那样使用OpenMP编译 ImageMagick ,这可能会特别有用。

Essentially, I am echoing all the commands instead of running them and the list of echoed commands is then run by GNU Parallel. This could be especially useful if you cannot compile ImageMagick with OpenMP as Eric suggested.

您可以使用<$ c $等开关c> - eta parallel 之后查看完成所需的时间,或 - 进度。此外,根据 big 您的计算机的实例,使用 -j 2 -j4 进行试验。

You can play around with switches such as --eta after parallel to see how long it will take to finish, or --progress. Also, experiment with -j 2 or -j4 depending how big your machine is.

我做了一些基准测试,只是为了好玩。首先,我在640x480处制作了250张随机噪音的JPEG图像,然后运行了chepner的代码as-is - 耗时2分27秒。

I did some benchmarks, just for fun. First, I made 250 JPEG images of random noise at 640x480, and ran chepner's code "as-is" - that took 2 minutes 27 seconds.

然后,我使用了相同的图像集,但将循环更改为:

Then, I used the same set of images, but changed the loop to this:

for ((i=1, j=1; i <= num; i+=skip, j+=1)); do
   echo convert "${files[@]:i:seqnum}" -evaluate-sequence mean ~/timelapse/Images/Shutterdrag/$j.jpg
done | parallel

时间下降到35秒。

然后我把循环放回去了,并将所有输入文件改为MPC而不是JPEG,时间减少到36秒。

Then I put the loop back how it was, and changed all the input files to MPC instead of JPEG, the time went down to 36 seconds.

最后,我使用上面的MPC格式 GNU Parallel,时间减少到19秒。

Finally, I used MPC format and GNU Parallel as above and the time dropped to 19 seconds.

我没有使用RAMdisk,因为我在与你不同的操作系统上(并且拥有极快的NVME磁盘),但这对你也有很大的帮助。您也可以将输出文件写入RAMdisk,也可以使用MPC格式。

I didn't use a RAMdisk as I am on a different OS from you (and have extremely fast NVME disks), but that should help you enormously too. You could write your output files to RAMdisk too, and also in MPC format.

祝您好运,请告诉我们您的使用方法!

Good luck and let us know how you get on please!

这篇关于如何提高读写密集型imagemagick脚本的性能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆