2012-01-06 77 views
5

像使用BigInteger查找階乘的任務是一項CPU密集型任務,是否有加快此類進程的速度?我們可以在java中加速CPU密集型任務嗎?

例如:發現2000! 由於它只是一個單一的任務,我認爲這裏不需要線程(因爲運行這個程序或在一個線程中運行這個任務都必須執行這樣的CPU密集型的事情)。

我聽說Java 7爲計算密集型任務引入了一種新的並行機制。 那麼,我該如何執行這種事情呢?

+2

新並聯機制的教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin。html – Luciano 2012-01-06 18:06:16

+2

首先:不要使用BigInteger來乘大數。它使用的是O(n^2)而不是karatsuba的樸素乘法算法,它將是O(n log n)。 – Voo 2012-01-06 18:26:51

+1

@Voo微小的事實糾正:Karatsuba是'O(n^1.585)'。 FFT是靠近'O(n log n)'的那個。 – Mysticial 2012-01-06 18:55:52

回答

12

因子可以通過最終合併輕鬆拆分爲兩個任務。如果你喜歡,這是一種地圖縮減。

例子:

9! = (7*5*3*1) * (8*6*4*2) 

所以,你可以有兩個任務。

這可以概括爲任意數量的並行任務。

該解決方案與Java沒有任何關係,它是將「常規」解決方案轉換爲並行解決方案。

+0

這有另外的好處,我們乘以更小的數字在大多數情況下,即使不進行並行化,速度也會快得多。好的想法是,使用相同的想法將給每個CPU的順序任務分開。 – Voo 2012-01-06 18:28:19

2

它可以簡單地查詢提交的WolframAlpha,和幾分之一秒內回覆大概的答案(at least for 2,000!,甚至10,000,000,000!),而如果你只需要大階乘的近似,可能會更遠遠不夠。

以下是您自己編寫的關於challenges around calculating large factorials的維基百科文章,其中一些已經發現。

你真的想要做的就是儘量減少需要完成的工作總量。最簡單的方法是將結果存儲在一個表中,然後進行查找。包含所有這些值的表格可能非常大,但如果存儲不是您的情況的限制,那麼這是一種方法。

只是嘗試並行化它並不會節省您的CPU(除非您正在計算近似值,而不是精確數值),因爲您正在做同樣數量的總體工作,但將其分散開來。而且,並行化任何事情都會涉及一些開銷(線程間/進程間通信,如果問題空間足夠大,分佈式內存,各種各樣的事情)。其中並行任何算法是一個巨大的勝利的地方,就是當你能夠成功地分裂問題成小塊,並波及那些大塊出有效的足以讓時間來......

  • 發送塊搞出來
  • 有大塊計算
  • 將結果發送回
  • 合併結果

...成本更低(如時間,金錢,存儲,電力測量,或任何你限制資源是)比它做系列,和/或它提供了一些價值(時間,金錢,存儲等保存),以便它有效地彌補成本。

相關問題