1

たとえば、配列float []またはdouble []. それらをすぐに追加する必要があります。どうやってするの?このためのライブラリはありますか?

4

5 に答える 5

0

1 つの方法は、配列の分割を決定し、N スレッドに配列の指定された部分を読み取らせて、個々の合計を見つけることです。その後、最終スレッドは、これらの個々の合計をすべて加算して、最終出力を得ることができます。

于 2013-05-22T08:32:21.807 に答える
0

真に高性能なコーディングを行う必要はあまりありませんでしたが、リストを n 個のセグメント (コアごとに 1 個) に分割し、各コアが小計を出し、小計を合計します。値を乗算するように求められた場合、ワーカーが 0 に遭遇するとすぐに答えが得られます。

public class ArrayAdder {
    public double getTotal(double[] array) {
        Worker workers[] = new Worker[Runtime.getRuntime().availableProcessors()];
        for (int i = 0; i < workers.length - 1;i++) {
            workers[i] = new Worker(array, 
                    i * array.length / workers.length,
                    (i + 1) * array.length / workers.length);
        }
        workers[workers.length - 1] = new Worker(array, 
                (workers.length - 1) * array.length / workers.length,array.length);
        double total = 0;
        for (int i = 0;i < workers.length;i++) {
            try {
                workers[i].join();
                total += workers[i].getSum();
            } catch (InterruptedException e) {
                i--; //retry the wait for worker[i]
            }

        }
        return total;

    }
    static class Worker extends Thread {
        public Worker(double[] array, int start, int end) {
            super();
            this.array = array;
            this.start = start;
            this.end = end;
            start();
        }
        private double[] array;
        private int start;
        private int end;
        private double sum;
        @Override
        public void run() {
            for (int i=start;i < end;i++) {
                sum += array[i];
            }

        }
        public double getSum() { return sum; }
    }
}

BigDecimal予想される値の大きさに応じて、小計と合計を として格納することができます。もちろん、正確な答えが必要でない限り、それらを ints/longs として追加する方がはるかに高速です。明らかに、単にキャストしたりキャストしたりするだけでなく (より高速な場合があります)、丸めたいと考え、答えが~array.length / 2半分の時間で、キャストはそれを間違った方向に「丸め」ます。

于 2013-05-22T08:52:05.437 に答える
0

別の最適化として考えられるのは、ループを部分的に展開して、CPU のスーパースカラー機能を使用することです。

たとえば、パイプライン サイズが 4 int のアーキテクチャ (および JVM がインテリジェントな場合) では、次のように記述できます。

for(int i = 0; i < array.size(); i += 4)
{
    c[i] = a[i] + b[i];
    c[i+1] = a[i+1] + b[i+1];
    c[i+2] = a[i+2] + b[i+2];
    c[i+3] = a[i+3] + b[i+3];
}

ただし、異なるアーキテクチャ パイプライン サイズごとに異なるコードを記述する必要があります。

于 2013-07-25T07:20:03.327 に答える