- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对多线程非常陌生,并且没有太多使用内部类的经验。
任务是以并行方式添加两个包含 double 值的矩阵。
我的想法是递归地执行此操作,将大矩阵拆分为较小的矩阵,并在矩阵达到一定大小限制时执行加法,然后融合它们。
并行化代码的运行速度比序列化代码慢 40-80 倍。
我怀疑我在这里做错了什么。也许是因为我创建了很多新矩阵,或者因为我遍历了它们很多次。
这是代码:
package concurrency;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ParallelMatrixAddition {
public static void main(String[] args) {
Random rand = new Random();
final int SIZE = 1000;
double[][] one = new double[SIZE][SIZE];
double[][] two = new double[SIZE][SIZE];
double[][] serialSums = new double[SIZE][SIZE];
double[][] parallelSums = new double[SIZE][SIZE];
for (int i = 0; i < one.length; i++) {
for (int j = 0; j < one.length; j++) {
one[i][j] = rand.nextDouble();
two[i][j] = rand.nextDouble();
}
}
long serialStartTime = System.currentTimeMillis();
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
serialSums[i][j] = one[i][j] + two[i][j];
}
}
long serialEndTime = System.currentTimeMillis();
System.out.println("Serial runtime is: " + (serialEndTime - serialStartTime) + " milliseconds");
long startTime = System.currentTimeMillis();
parallelSums = parallelAddMatrix(one, two);
long endTime = System.currentTimeMillis();
System.out.println("Parallel execution took " + (endTime - startTime) + " milliseconds.");
}
public static double[][] parallelAddMatrix(double[][] a, double[][] b) {
RecursiveTask<double[][]> task = new SumMatricesTask(a, b);
ForkJoinPool pool = new ForkJoinPool();
double[][] result = new double[a.length][a.length];
result = pool.invoke(task);
return result;
}
@SuppressWarnings("serial")
private static class SumMatricesTask extends RecursiveTask<double[][]> {
private final static int THRESHOLD = 200;
private double[][] sumz;
private double[][] one;
private double[][] two;
public SumMatricesTask(double[][] one, double[][] two) {
this.one = one;
this.two = two;
this.sumz = new double[one.length][one.length];
}
@Override
public double[][] compute() {
if (this.one.length < THRESHOLD) {
// Compute a sum here.
// Add the sums of the matrices and store the result in the
// matrix we will return later.
double[][] aStuff = new double[this.one.length][this.one.length];
for (int i = 0; i < one.length; i++) {
for (int j = 0; j < one.length; j++) {
aStuff[i][j] = this.one[i][j] + this.two[i][j];
}
}
return aStuff;
} else {
// Split a matrix into four smaller submatrices.
// Create four forks, then four joins.
int currentSize = this.one.length;
int newSize = currentSize / 2;
double[][] topLeftA = new double[newSize][newSize];
double[][] topLeftB = new double[newSize][newSize];
double[][] topLeftSums = new double[newSize][newSize];
double[][] topRightA = new double[newSize][newSize];
double[][] topRightB = new double[newSize][newSize];
double[][] topRightSums = new double[newSize][newSize];
double[][] bottomLeftA = new double[newSize][newSize];
double[][] bottomLeftB = new double[newSize][newSize];
double[][] bottomLeftSums = new double[newSize][newSize];
double[][] bottomRightA = new double[newSize][newSize];
double[][] bottomRightB = new double[newSize][newSize];
double[][] bottomRightSums = new double[newSize][newSize];
// Populate topLeftA and topLeftB
for (int i = 0; i < newSize; i++) {
for (int j = 0; j < newSize; j++) {
topLeftA[i][j] = this.one[i][j];
topLeftB[i][j] = this.two[i][j];
}
}
// Populate bottomLeftA and bottomLeftB
for (int i = 0; i < newSize; i++) {
for (int j = 0; j < newSize; j++) {
bottomLeftA[i][j] = this.one[i + newSize][j];
bottomLeftB[i][j] = this.two[i + newSize][j];
}
}
// Populate topRightA and topRightB
for (int i = 0; i < newSize; i++) {
for (int j = 0; j < newSize; j++) {
topRightA[i][j] = this.one[i][j + newSize];
topRightB[i][j] = this.two[i][j + newSize];
}
}
// Populate bottomRightA and bottomRightB
for (int i = 0; i < newSize; i++) {
for (int j = 0; j < newSize; j++) {
bottomRightA[i][j] = this.one[i + newSize][j + newSize];
bottomRightB[i][j] = this.two[i + newSize][j + newSize];
}
}
SumMatricesTask topLeft = new SumMatricesTask(topLeftA, topLeftB);
SumMatricesTask topRight = new SumMatricesTask(topRightA, topRightB);
SumMatricesTask bottomLeft = new SumMatricesTask(bottomLeftA, bottomLeftB);
SumMatricesTask bottomRight = new SumMatricesTask(bottomRightA, bottomRightB);
topLeft.fork();
topRight.fork();
bottomLeft.fork();
bottomRight.fork();
topLeftSums = topLeft.join();
topRightSums = topRight.join();
bottomLeftSums = bottomLeft.join();
bottomRightSums = bottomRight.join();
// Fuse the four matrices into one and return it.
for (int i = 0; i < newSize; i++) {
for (int j = 0; j < newSize; j++) {
this.sumz[i][j] = topLeftSums[i][j];
}
}
for (int i = newSize; i < newSize * 2; i++) {
for (int j = 0; j < newSize; j++) {
this.sumz[i][j] = bottomLeftSums[i - newSize][j];
}
}
for (int i = 0; i < newSize; i++) {
for (int j = newSize; j < newSize * 2; j++) {
this.sumz[i][j] = topRightSums[i][j - newSize];
}
}
for (int i = newSize; i < newSize * 2; i++) {
for (int j = newSize; j < newSize * 2; j++) {
this.sumz[i][j] = bottomRightSums[i - newSize][j - newSize];
}
}
return this.sumz;
}
}
}
}
感谢您的帮助。
最佳答案
即使对于 double
,创建对象也比执行 +
慢很多倍。
这意味着创建一个对象对于添加来说并不是一个好的权衡。更糟糕的是,使用更多内存意味着您的 CPU 缓存无法高效工作,在最坏的情况下,在 L1/L2 cpu 缓存中工作的内容现在位于 L3 缓存中,该缓存是共享的且不可扩展,甚至更糟您最终会使用主内存。
我建议你重写这个,以便
关于java - 为什么这种并行矩阵加法效率如此低下?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34066423/
假设我有两个矩阵,每个矩阵有两列和不同的行数。我想检查并查看一个矩阵的哪些对在另一个矩阵中。如果这些是一维的,我通常只会做 a %in% x得到我的结果。 match似乎只适用于向量。 > a
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 个月前。 Improv
我只处理过 DirectX 矩阵 我读过一些文章,说不能将 DirectX 矩阵数学库用于 openGL 矩阵。 但我也读过,如果你的数学是一致的,你可以获得类似的结果。那只会让我更加困惑。 任何人都
我编写了一个C++代码来解决线性系统A.x = b,其中A是一个对称矩阵,方法是首先使用LAPACK(E)对角矩阵A = V.D.V^T(因为以后需要特征值),然后求解x = A^-1.b = V^T
我遇到了问题。我想创建二维数组 rows=3 cols=2我的代码如下 int **ptr; int row=3; int col=2; ptr=new int *[col]; for (int i=
我有一个 3d mxnxt 矩阵,我希望能够提取 t 2d nxm 矩阵。在我的例子中,我有一个 1024x1024x10 矩阵,我想要 10 张图像显示给我。 这不是 reshape ,我每次只需要
我在 MATLAB 中有一个 3d 矩阵 (n-by-m-by-t) 表示一段时间内网格中的 n-by-m 测量值.我想要一个二维矩阵,其中空间信息消失了,只剩下 n*m 随着时间 t 的测量值(即:
作为一个简化的示例,我有一个 3D numpy 矩阵,如下所示: a = np.array([[[1,2], [4,np.nan], [7,
作为一个简化的示例,我有一个 3D numpy 矩阵,如下所示: a = np.array([[[1,2], [4,np.nan], [7,
使用 eigen2 , 并给定一个矩阵 A a_0_0, a_0_1, a_0_2, ... a_1_0, a_1_0, a_1_2, ... ... 和一个矩阵B: b_0_0, b_0_1, b_
我想知道如何获得下面的布局。 在中型和大型设备上,我希望有 2 行和 2 列的布局(2 x 2 矩阵)。 在小型(和超小型)设备上或调整为小型设备时,我想要一个 4 行和 1 列的矩阵。 我将通过 a
有什么方法可以向量化以下内容: for i = 1:6 te = k(:,:,:,i).*(c(i)); end 我正在尝试将 4D 矩阵 k 乘以向量 c,方法是将其
如何从填充有 1 和 0 的矩阵中抽取 n 个随机点的样本? a=rep(0:1,5) b=rep(0,10) c=rep(1,10) dataset=matrix(cbind(a,b,c),nrow
我正在尝试创建一个包含 X 个 X 的矩阵。以下代码生成从左上角到右下角的 X 对 Angular 线,而不是从右上角到左下角的 X 对 Angular 线。我不确定从哪里开始。是否应该使用新变量创建
我想在 python 中创建一个每行三列的矩阵,并能够通过任何一行对它们进行索引。矩阵中的每个值都是唯一的。 据我所知,我可以设置如下矩阵: matrix = [["username", "name"
我有点迷茫 我创建了一个名为 person 的类,它具有 age 和 name 属性(以及 get set 方法)。然后在另一个类中,我想创建一个 persons 数组,其中每个人都有不同的年龄和姓名
我有 n 个类,它们要么堆叠,要么不堆叠。所有这些类都扩展了同一个类 (CellObject)。我知道更多类将添加到此列表中,我想创建一种易于在一个地方操纵“可堆叠性”的方法。 我正在考虑创建一个矩阵
我有一个包含 x 个字符串名称及其关联 ID 的文件。本质上是两列数据。 我想要的是一个格式为 x x x 的相关样式表(将相关数据同时作为 x 轴和 y 轴),但我想要 fuzzywuzzy 库的函
机器学习与传统编程的一个重要区别在于机器学习比传统编程涉及了更多的数学知识。不过,随着机器学习的飞速发展,各种框架应运而生,在数据分析等应用中使用机器学习时,使用现成的库和框架成为常态,似乎越来越不需
当我在 julia 中输入这个错误跳转但我不知道为什么,它应该工作。/ julia> A = [1 2 3 4; 5 6 7 8; 1 2 3 4; 5 6 7 8] 4×4 Array{Int64,
我是一名优秀的程序员,十分优秀!