1

並行して実行されるプログラムを作成するために、Java で Thread-ing を学習しています。並列処理を使用してプログラムを設計することは、学校のプログラミングの授業で学ぶ機会がなかったものです。スレッドを作成して実行する方法は知っていますが、それらを効率的に使用する方法はわかりません。結局のところ、プログラムを高速にするのは実際にスレッドを使用することではなく、優れた並列設計であることはわかっています。そこで、自分の知識をテストするためにいくつかの実験を行いました。ただし、私の並列バージョンは、実際には比類のないものよりも遅く実行されます。私は本当にその考えを理解しているかどうか疑問に思い始めます。もしよろしければ、私の次のプログラムを見ていただけませんか?

分割統治方式で配列を埋めるプログラムを作成しました (Java に Arrays.fill ユーティリティがあることは知っていますが、マルチスレッドで自分の知識をテストしたいだけです)。

public class ParalledFill
{
    private static fill(final double [] array, 
                        final double value, 
                        final int start, 
                        final int size)
    {
        if (size > 1000) 
        { // Each thread handles at most 1000 elements
            Runnable task = new Runnable() { // Fork the task
                public void run() { 
                    fill(array, value, start, 1000); // Fill the first 1000 elements
            }};
            // Create the thread
            Thread fork = new Thread(task);
            fork.start(); 
            // Fill the rest of the array
            fill(array, value, start+1000, size-1000);
            // Join the task
            try {
                fork.join();
            }
            catch (InterruptedException except)
            {
                System.err.println(except);
            }
        }
        else 
        { // The array is small enough, fill it via a normal loop
            for (int i = start; i < size; ++i)
            array[i] = value;
        }
    } // fill

    public static void main(String [] args)
    {
        double [] bigArray = new double[1000*1000];
        double value = 3;
        fill(bigArray, value, 0, bigArray.length);
    }
}

このプログラムをテストしましたが、次のようなことを行うよりもさらに遅いことがわかりました。

for (int i = 0; i < bigArray.length; ++i)
    bigArray[i] = value;

私の推測では、Java がループを使用して配列を埋めるための最適化を行っている可能性があり、これにより、私のスレッド化されたバージョンよりもはるかに高速になります。しかし、それ以外では、スレッド/並列処理の処理方法が間違っている可能性があると強く感じています。私はスレッドを使用して何かを設計したことはありません (常にコンパイラの最適化または C の OpenMP に依存していました)。私の並列バージョンが速くない理由を説明してくれる人はいますか? 並列化されたプログラムを設計するという点で、そのプログラムはあまりにも悪かったのでしょうか?

ありがとう、シン。

4

1 に答える 1

0

複数の CPU を使用したり、I/O のような実行時間の長いタスクを使用したりしない限り、実行しているのはスレッド間のタイム スライスだけだと思います。実行する作業が非常に多い単一の CPU がある場合、スレッドを追加しても、実行する必要がある作業は減少しません。あなたがすることは、コンテキストの切り替えによるオーバーヘッドを追加することだけです。

「Java Concurrency In Practice」を読む必要があります。生のスレッドではなく、最新の同時実行パッケージを使用して物事を行う方法を学ぶことをお勧めします。

于 2013-11-01T20:42:43.473 に答える