java - 为什么使用大于内核的 Executor 来加速并行编程?
问题描述
我正在编写一个使用 Executorservice 框架处理矩阵并行编程的程序。而且我将fixedpoolsize设置为4,但令我惊讶的是,当矩阵维度设置为5000时,使用多线程对串行执行的加速大于4(这也是我的CPU内核)。而且我已经检查过我的 CPU 不支持超线程。
实际上,我使用 Callable 和 Future 容器,因为我的多线程任务需要返回结果。
// Part of code for parallel programming
double[][] x = new double[N][N];
List<Future<double[]>> futureList = new ArrayList<>();
for (int k=0;k<N;k++)
{
Future<double[]>temp=service.submit(new Thread.Task(N,k,matrix,vector));
futureList.add(temp);
}
for (int j = 0; j < N; j++) {
x[j]=futureList.get(j).get();
}
public double[] call() throws Exception {
for (int i = N - 1; i >= 0; i--)
{
double sum = 0;
for (int j = i + 1; j < N; j++)
{
sum += matrix[i][j] * x[j];
}
x[i] = (vector[i][k] - sum) / matrix[i][i];
}
return x;
}
// Part of code for Serial programming
double[][] x = new double[N][N];
for (int k=0;k<N;k++)
{
for (int i = N - 1; i >= 0; i--)
{
double sum = 0;
for (int j = i + 1; j < N; j++)
{
sum += matrix[i][j] * x[j][k];
}
x[i][k] = (vector[i][k] - sum) / matrix[i][i];
}
}
简而言之,我只是将内部循环拿走,让它由线程运行,而外部循环保持不变。
但是加速怎么可能是这样的呢?
因为从我之前的概念来看,最大加速只能是 4。我已经检查过该任务实际上是由 4 个线程完成的。
解决方案
这可能是 CPU 缓存亲和性的影响。如果每个核心处理问题的不同部分,它可能会在缓存使用方面实现更高的效率。因为 RAM 比缓存慢 10 倍或更多倍,所以这会产生巨大的差异。
推荐阅读
- javascript - 循环填充 div 中的剩余空间
- c# - 构造私有字段可访问性
- qt - qmake:警告:没有规则使目标停止
- php - laravel php curl 请求 Finerworks api
- powershell - 在 c:\Program files(x86)\zabbix 文件夹中使用 Powershell 安装/卸载 Zabbix
- processing - 如何以另一种(初学者)方式编写此处理代码?
- swift - 为什么这个标签没有显示正确的值?迅速
- css - 为什么我的通用选择器会覆盖我的元素选择器?
- typescript - 将 Object.values 与 Records 联合使用时避免隐式 `any`
- sql - Sqlite Query, Group_Concat 的多个左连接和嵌套查询