使用多线程求和整数 - 奇怪的结果?

时间:2015-04-05 02:35:37

标签: java arrays multithreading

我有两种方法可以对数组中的一组整数求和。

依序:

public static long sumSlow(int[] data) {
    long sum = 0;
    for (int i : data) {
        sum += i;
    }
    return sum;
}

并行(我参与数组,并使用一个线程对数组的每个部分求和):

public static long sum(int[] data, int threadcnt) {

    int partitionSize = data.length / threadcnt;

    Sum[] sums = new Sum[threadcnt];
    Thread[] threads = new Thread[threadcnt];

    for (int i = 0; i < threadcnt; i++) {
        sums[i] = new Sum(data, i * partitionSize, (i + 1) * partitionSize);
        threads[i] = new Thread(sums[i]);
        threads[i].start();
    }

    // wait for all the threads to finish summing
    try {
        for (Thread t : threads) {
            t.join();
        }
    } catch (InterruptedException ie) {
    }

    long total = 0;
    for (Sum sum : sums) {
        total += sum.getSum();
    }

    return total;
}

Sum是一个Runnable类,它由一个整数数组,一个起始索引和一个结束索引构成。当对象运行时,它使用一个长成员变量根据索引对元素进行求和(我不认为我需要使用AtomicLong,因为数据总是只由一个线程使用,但是如果我在我错了)。

现在,我对两种方法都进行了一些测试:

    // create file to export data
    PrintWriter writer = new PrintWriter("results.txt");

    // 20 tests
    for (int i = 0; i < 20; i++) {

        // create the array
        int[] data = randomArray(512);

        // sum the values sequentially, get time
        long sequentialStart = System.nanoTime();

        long s1 = sumSlow(data);

        double sequentialTime = (System.nanoTime() - sequentialStart) / 1e9;

        // sum the values parallely, get time
        double parallelStart = System.nanoTime();

        long s2 = sum(data, 2);

        double parallelTime =  (System.nanoTime() - parallelStart) / 1e9;

        // error checking
        if (s1 != s2) {
            System.err.println("Summing method incorrect.");
            System.exit(1);
        }

        String content = String.format("%f %f", sequentialTime, parallelTime);
        writer.println(content);
    }
    writer.close();
}

以下是我对此测试的结果(2个核心,数组大小:512) 左侧是连续时间,右侧是平行时间。

0.000058 0.004966
0.000036 0.000973
0.000034 0.000649
0.000036 0.000724
0.000034 0.000627
0.000035 0.000690
0.000034 0.000817
0.000036 0.000665
0.000034 0.000793
0.000052 0.000940
0.000047 0.001023
0.000049 0.001216
0.000039 0.001821
0.000051 0.001186
0.000048 0.000826
0.000052 0.000918
0.000034 0.000802
0.000036 0.000723
0.000034 0.000587
0.000036 0.000917

为什么我的结果是这样的?更清楚的是,为什么顺序方法比并行方法更快?或者我只是错误地读取我的数据/写错我的测试?我检查了这个以获得更多线程和更多索引,并且模式是相同的。为什么会这样?

0 个答案:

没有答案