我有一个程序可以对一个非常大的数组中的元素求和。我想并行化这个总和。
#define N = some_very_large_no; // say 1e12
float x[N]; // read from a file
float sum=0.0;
main()
{
for (i=0, i<N, i++)
sum=sum+x[i];
}
如何使用线程并行化这个总和(c/c++/Java 任何代码示例都可以)?如果机器中有 8 个核心,我应该使用多少个线程才能获得最佳性能?
编辑:N 可能非常大(实际上大于 1e6),并且根据我从中读取数据的文件大小而变化。该文件的大小为 GB。
编辑:N更改为较大值(1e12到1e16)
最佳答案
在 Java 中你可以这样写
int cpus = Runtime.getRuntime().availableProcessors();
// would keep this of other tasks as well.
ExecutorService service = Executors.newFixedThreadPool(cpus);
float[] floats = new float[N];
List<Future<Double>> tasks = new ArrayList<>();
int blockSize = (floats.length + cpus - 1) / cpus;
for (int i=0, i < floats.length, i++) {
final start = blockSize * i;
final end = Math.min(blockSize * (i+1), floats.length);
tasks.add(service.submit(new Callable<Double>() {
public Double call() {
double d= 0;
for(int j=start;j<end;j++)
d += floats[j];
return d;
}
});
}
double sum = 0;
for(Future<Double> task: tasks)
sum += task.get();
正如 WhozCraig 提到的,一百万个浮点可能不足以需要多个线程,或者您可能会发现您的瓶颈是从主内存(单个线程资源)加载数组的速度在任何情况下在这种情况下,您不能假设在包含获取数据的成本时速度会更快。
关于java - 大型数组中元素的并行求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16272384/