我有两种方法可以对数组中的一组整数求和。
依序:
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
为什么我的结果是这样的?更清楚的是,为什么顺序方法比并行方法更快?或者我只是错误地读取我的数据/写错我的测试?我检查了这个以获得更多线程和更多索引,并且模式是相同的。为什么会这样?