2012-01-06 12 views
5

BigIntegerを使用するCPU集約型タスクである2000の階乗のようなタスクは、このようなプロセスをスピードアップするために存在しますか?JavaでCPU集約型タスクを高速化できますか?

例:find 2000! これは単なるタスクなので、ここではスレッドの必要はないと思う(このプログラムを実行している、またはスレッド内でこのタスクを実行しているので、CPU集約的なことを実行しなければならない)。

私は、Java 7が計算集約型タスクのための新しい並列メカニズムを導入したと聞いたことがあります。 それで、私はどのようにこのようなことを実行しますか?

+2

新しいパラレルメカニズムのチュートリアル:http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoinhtml – Luciano

+2

まず、BigIntegerを使用して大きな数値を乗算しないでください。これは、O(n log n)となるkaratsubaの代わりにO(n^2)という素朴な乗算アルゴリズムを使用しています。 – Voo

+1

@Voo小さな事実の修正:Karatsubaは 'O(n^1.585)'です。 FFTは 'O(n log n)'の近くにあるものです。 – Mysticial

答えて

12

階乗は、最後のマージで2つのタスクに簡単に分割できます。あなたが好きなら、これはmap-reduceの一種です。

例:

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

だから、2つのタスクを持つことができます。

これは、任意の量の並列タスクに一般化できます。

このソリューションは、Javaとはまったく関係がありません。これは、「通常の」ソリューションをパラレルのソリューションに変換することです。

+0

これは、私たちがはるかに小さい数字を乗算しているという付加的な利点がありますあなたがそれを並列化していなくてもずっと速いです。同じアイデアを使って各CPUに与えられたシーケンシャルタスクを分割することをお勧めします。 – Voo

2

それは単にWolframAlphaにクエリを提出し、第二の割合以内にあなただけの大規模な階乗の近似が必要な場合は、(at least for 2,000!、あるいは10,000,000,000!)を、おおよその答えを取り戻すことは可能ですが、おそらくよりになります十分です。

challenges around calculating large factorialsのウィキペディアの記事があります。そのうちのいくつかは既に発見済みです。

本当にやりたいことは、実行する必要のある作業の総量を減らすことです。これを行う最も簡単な方法は、結果をテーブルに格納してルックアップを行うことです。これらの値をすべて含む表は非常に大きくなる可能性がありますが、状況によっては記憶域が制限されていない場合の1つの方法です。

単純に並列化しようとしても、正確な数値ではなく近似値を計算しない限り、CPUを節約することはできません。また、何かを並列化するには、いくつかのオーバーヘッド(スレッド間/プロセス間通信、問題空間が十分大きい場合は分散メモリ、すべての種類のもの)が必要です。あなたが成功した小さな塊に問題を分割し、へ...

  • 時間が出てチャンクを送信するように効率的に十分なこれらのチャンクを広げることができたときに任意のアルゴリズムを並列化することは大きな勝利である場所が、あります
  • を算出したチャンクがバック
  • の結果を送信している
  • は結果

を組み合わせて...あまり、時間に測定された(高価なお金、ストレージ、電気、または何でもあなたが限られていますそれはそれが効果的にコストを補うように、何らかの価値(時間、金銭、保管などが保存された)を提供するということです。

関連する問題