2016-12-30 24 views
1

我有一個NodeJS程序,它使用ImageMagick從我的分區中的一些文本創建圖像。該方案是從我的NodeJs服務器使用當我開始新的分支進程時,NodeJS分叉進程正在減慢所有其他分支進程

import childProcess from 'child_process'; 
let args = [':imageId', '--max_old_space_size=4096']; 
childProcess.fork('createImage.js', args); 

創建圖像的過程中午飯是它可能需要5-6min我的本地機器上的單張圖像大小爲114x84cm相當緩慢。

我會嘗試解釋程序生命週期中發生了什麼。

因此,我有服務器運行在進程MyServer,當有人請求圖像MyServer叉出一個新的進程。

新進程ImageCreator1有一個來自promise的循環,並且會一直等到全部解決。每個承諾創建使用ImageMagick

在我的活動監視器大圖像的一部分,我可以看到,有一些正在運行的進程

Process Name | %CPU 
MyServer  - 0.3 
ImageCreator1 - 30.0 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 

我也可以看到,ImageCreator1運行異步4-5 ImageMagick轉換進程創建所有這些需要的小圖像。

這一切都需要5分鐘。創造大的形象。

所以當我開始兩個ImageCreators的時間增加到9分鐘。

Process Name | %CPU 
MyServer  - 0.3 
ImageCreator1 - 30.0 
ImageCreator2 - 40.0 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 
convert  - 0.1 
convert  - 0.1 
convert  - 0.2 
convert  - 0.1 

,如果我開始ImageCreator3ImageCreator4是越來越慢。我在想,當我開始一個新的過程,並且如果這個過程完成了5分鐘的工作。然後,如果我同時啓動五個流程,則每個流程都必須完成5分鐘。但似乎每個新的ImageCreator的時間都增加了。

我還在學習階段NodeJs和這個OS的東西,所以如果有人能解釋發生了什麼將是偉大的。

!!!更新IMAGECREATOR代碼!!!

console.time('imageCreator'); 
process.title = 'imageCreator'+process.argv[2]; 

const fs = require('fs'); 
const gm = require('gm').subClass({imageMagick:true}); 
const Promise = require('bluebird'); 

var images = [], rows = []; 
for(var i = 1; i<=100;i++){ 
    images.push(i); 
} 

for(var i = 1; i<=10;i++){ 

    rows.push(Promise.reduce(images, function(total, image){ 

     return new Promise(function(resolve, reject) { 

      gm('xc:rgb('+(image*2)+','+image+','+(image*2)+')') 
      .in('-units', 'PixelsPerInch') 
      .in('-size', '100x100') 
      .in('-density', 300) 
      .in('-page', '+'+(image-100)*100+'+0') 
      .toBuffer('miff', function(err, stream){ 
        fs.appendFile(__dirname+'/test'+process.argv[2]+'.miff', stream, function(err){ 
         if(err) reject(err); 
         else resolve(image); 
        }); 
      }); 

     }); 

    })); 

} 


Promise.all(rows).then(function() { 
    console.timeEnd('imageCreator'); 
}); 

所以我正在做一些測試,以找出我的腳本的哪些部分是有問題的。這裏是一個例子,當我在我的Mac上運行這個時發生了什麼。順便說一句我也重新編譯的ImageMagick所以現在我有:

Version: ImageMagick 6.9.7-2 Q16 x86_64 2017-01-03 http://www.imagemagick.org 
Copyright: © 1999-2017 ImageMagick Studio LLC 
License: http://www.imagemagick.org/script/license.php 
Features: Cipher DPC Modules 
Delegates (built-in): bzlib freetype jng jpeg ltdl lzma png tiff xml zlib 

所以,當我一個終端上運行上面的腳本中,我得到這樣的時候:

Terminal1 - imageCreator: 7498.438ms - 7.4984380002sec. 

但是當我嘗試在兩個接線端子同一時間:

Terminal1 - imageCreator: 14632.522ms - 14.632522sec. 
Terminal2 - imageCreator: 13734ms - 13.734sec. 

正如你所看到的,兩者的時間差不多加倍。

我的電腦有:

processor:2.7 GHz Intel Core i5 
memory:8 GB 1867 MHz DDR3 

所以這是怎麼回事,我猜RAM這裏所涉及的,但我不是非常好,這種低層次的東西,所以如果有人可以解釋將是巨大的。先謝謝你。

+0

說一個圖像是114釐米x 84釐米並沒有告訴我們太多 - 在1 dpi的dpi將是9,000像素,但在600dpi它將是3,500,000,000像素。 –

+0

抱歉,對於遲來的答案,圖片的dpi是300dpi,但這真的很重要嗎?比方說,如果我的進程正在運行並以72dpi轉換圖像,並且此進程正在運行,那麼我將啓動另一個進程,兩者的時間都會增加。我不知道這個問題是否在ImageMagick或nodejs中,需要做更多的測試,我會嘗試@rdegges共享鏈接建議使用--disable-openmp編譯ImageMagick,並將模擬我的nodejs程序在沒有ImageMagick的情況下運行,結果。謝謝你的評論。 – Alex

+0

我的意思是,114釐米x 84釐米是45英寸x 33英寸。因此,在300 dpi下,您的圖像將具有45 * 300 * 33 * 300像素,即133百萬像素。如果是3色(RGB)和16位/像素的顏色,則需要將其乘以6,因此每幅圖像需要800MB的RAM,最小值爲。也許你應該在'ImageCreator'中顯示代碼,並查看你的進程的內存限制,因爲你可能會將內存分頁到磁盤。 –

回答

1

您執行此代碼的計算機有多少個CPU核心?當你用child_process創建一個新進程時,你正在開始一個新進程 - 這意味着OS調度程序將試圖與你的父進程並行地運行新進程 - 但是這個需要多個CPU的

如果您沒有多個CPU,將會發生什麼情況是操作系統調度程序將在運行主進程和子進程之間開始交換,並在同一CPU上給每個CPU時間,從而不會真正運行他們在'並行',因爲在任何給定的時間只有一個指令將被執行。

另一件需要注意的事情是ImageMagick:在多個進程中運行安全嗎?

我對ImageMagick並不是很熟悉,但是根據2009年的this old thread(現在可能會有所不同),ImageMagick使用自己的線程:所以在多個進程中同時運行它不會導致任何加速。

希望有幫助!