2012-11-12 31 views
5

我一直在尋找優化一個ruby程序,對大量數據計算密集的程序。我不知道C並選擇了Ruby(不是我也很瞭解它),除了執行所需的時間之外,我對結果非常滿意。這是很多數據,並且不花錢,我想知道我能做些什麼來確保我最大化自己的系統資源。在所有處理器上運行ruby程序

當我運行基本的Ruby程序時,它是否使用單個處理器?如果我沒有專門分配任務給處理器,Ruby將不會讀取我的程序並且神奇地加載每個處理器以儘可能快地完成程序?我假設沒有...

我一直在閱讀有關加速Ruby,並在另一個線程閱讀,Ruby不支持真正的多線程(雖然它說JRuby的確)。但是,如果我要將程序「分解」爲兩個塊,可以在單獨的實例中運行,並在parralel中運行這些塊......這兩個塊是否會自動運行在兩個獨立的處理器上?如果我有四個處理器並打開四個外殼並運行四個獨立部分(1/4)的程序 - 它會在1/4的時間內完成嗎?

更新

閱讀評論後,我決定給JRuby一槍。移植應用程序並不困難。我還沒有使用過「桃子」,但通過在JRuby中運行它,該應用程序在1/4時間內運行!瘋。我沒有期待這麼大的改變。現在就去投一次,看看這是如何改善的。仍然無法相信這種提振。

更新#2

剛給了桃子一試。結束了另外15%的時間削減。所以切換到JRuby並使用Peach絕對是值得的。

謝謝大家!

+0

沒有看到源代碼,我們猜測可以做些什麼來加快你的應用程序。儘管如此,如果你正在以艱難/緩慢的方式做一些事情,可能會加快一點。 –

回答

4

使用JRuby和peach寶石,它不會更容易。只需將.each替換爲.peach即可,並行執行。還有其他選項可以精確控制產生的線程數量等等。我已經使用了它,它工作得很好。

您接近n倍加速,其中n是可用的CPU /內核的數量。我發現線程的最佳數量略多於CPU /內核的數量。

0

線程通常被認爲是Ruby的弱點之一,但它更多地取決於您使用的Ruby的哪個實現。

對不同線程模型的一個很好的寫法是「Does ruby have real multithreading?」。

從我的經驗和從對這些東西有更多瞭解的人那裏瞭解到的情況看來,如果您要選擇Ruby實現,那麼JRuby就是要走的路。但是,如果你正在學習Ruby,你可能想要選擇另一種語言,比如Erlang,或者Clojure,如果你想使用JVM,它們是流行的選擇。

0

和紅寶石一樣好,它的執行速度並不爲人所知。也就是說,如果您的評論中指出,如果您可以將輸入分解爲相同大小的塊,則應該能夠啓動n個程序實例,其中n是您擁有的核心數,操作系統將照顧你所有的核心。

在最好的情況下,它會在1/n的時間內運行,但這種事情可能會非常棘手,因爲系統的某些部分(如內存)需要在進程之間共享和爭用過程會導致事物不能線性縮放。如果拆分很容易,我會試試看。您也可以嘗試運行同一個程序兩次,查看運行需要多長時間,如果運行一個程序的時間與運行兩個程序的時間相同,您可能已經設置了這兩個程序,只需分割數據並轉至它。

嘗試jruby和一些線程可能會有所幫助,但這增加了相當多的複雜性。 (這可能是學習線程的一個很好的藉口。)

2

像其他人一樣,紅寶石的MRI實現(大多數人使用的)不支持本地線程。因此,通過使用MRI實現啓動更多線程,您不能在CPU內核之間分割工作。

但是,如果您的進程是IO限制的(例如受磁盤或網絡活動限制),那麼您仍可能受益於多個MRI線程。

另一方面,JRuby支持本地線程,這意味着您可以使用線程在CPU內核之間分割工作。

但一切都不會丟失。通過MRI(以及所有其他Ruby實現),仍然可以使用進程來分割工作。

這可以使用Process.fork例如這樣進行:

Process.fork { 
    10.times { 
    # Do some work in process 1 
    sleep 1 
    puts "Hello 1" 
    } 
} 

Process.fork { 
    10.times { 
    # Do some work in process 2 
    sleep 1 
    puts "Hello 2" 
    } 
} 

# Wait for the child processes to finish 
Process.wait 

使用fork將拆分CPU內核之間的處理,所以如果你生活中可以沒有線程再分離的過程是這樣做的一種方式。