2010-12-06 76 views
1

我正在製作一個系統。這是一個複雜的系統,但它歸結爲一個Solver類這樣的方法:該方法有望如何讓此Java代碼可並行化?我如何使它變得易變

public int solve(int problem); // returns the solution, or 0 if no solution found 

現在,當系統啓動並運行,約5秒的運行時間,是完全足夠快。不過,我計劃運行一些測試,看起來有點像這樣:

List<Integer> problems = getProblems(); 
List<Integer> solutions = new ArrayList<Integer>(problems.size); 
Solver solver = getSolver(); 
for (int problem: problems) { 
    solutions.add(solver.solve(problem)); 
} 
// see what percentage of solutions are zero 
// get arithmetic mean of non-zero solutions 
// etc etc 

的問題是我想在大量問題上運行這一點,不想永遠等待結果。所以說,我有一百萬的測試問題,我想在測試中它需要我做一杯茶的時間內完成,我有兩個問題:

  1. 說我有一萬芯處理器和實例Solver是線程安全的,但沒有鎖定(它們是不可變的或其他),並且它們所做的所有計算都在內存中(即沒有磁盤或網絡或其他內容)。我可以用線程安全列表替換解決方案列表並啓動線程來解決每個問題,並期望它更快嗎?快多少?它可以在5秒內運行嗎?

  2. 是否有一個體面的雲計算服務在那裏的Java,我可以購買500萬秒的時間,讓這個代碼運行在五秒鐘?我需要做什麼來準備我的代碼以在這樣的雲上運行?無論如何,500萬秒的成本是多少?

謝謝。

回答

0

你在問非常大的問題。線程的開銷很大,需要注意的一點是它們在父進程中運行。如果你想同時運行一百萬個解算器,你必須將它們分解到他們自己的進程中。

0

您可以對每個輸入使用一個程序,然後使用像Condor(用於Linux)或HPC(用於Windows)的簡單批處理調度程序。你也可以在亞馬遜上運行它們,但是有一些學習曲線,它不僅僅是「上傳Java代碼&」。

0
  1. 當然,您可以使用標準的工作線程範例並行運行。但是會有一些同步開銷(例如,當解決方案列表更新會在所有事情嘗試同時完成時導致鎖爭用),因此它不會在5秒內運行。但速度將超過500萬秒:-)
  2. 根據您需要多少CPU(請參閱pricing),Amazon EC2每小時運行價格爲0.085至0.68美元。所以,大約120美元。當然,你需要設置一些獨立的東西來分配各種CPU的工作。一種選擇可能只是使用Hadoop的(見是否Hadoop is right for running simulations這個問題。

您可以閱讀之類的東西Guy Steele's talk on parallelism關於如何思考平行的詳細信息。

0

查閱這些文章併發:

基本上,Java 7中的新叉/加入模型將工作得很好了這種方法。從本質上講,您可以設置您的百萬個任務,並將它們儘可能擴展到所有可用的處理器。您將不得不提供您的自定義「雲」任務執行程序,但可以完成。

這當然假設你的「求解」算法是平行的。簡而言之,只要Solver是完全獨立的,它們應該能夠在任意數量的處理器之間分割。

1

你已經表達了你的問題有兩個主要的序列化問題:問題產生和解決方案消耗(目前表示爲整數列表)。你想盡快得到第一個問題(目前在產生所有問題之前你不會得到它們)。

我假設問題列表順序和解決方案列表順序之間存在關聯 - 即solutions.get(3)problems.get(3)的解決方案 - 這對於並行化是一個巨大的問題。你最好有一個問題/解決方案Pair<P, S>,所以你不需要保持相關性。並行化求解器方法並不困難,儘管你如何做到這一點將取決於每個求解方法的計算成本(通常這種方法越昂貴,平行化開銷成本越低,所以如果這些成本是非常便宜,你需要批量他們)。如果最終採用分佈式解決方案,那麼當然會有更高的成本。 Executor框架和fork/join擴展將是一個很好的起點。