我正在尝试比较顺序矩阵乘法和并发矩阵乘法。每次顺序都更快。例如,60 x 60 矩阵顺序找到 4 毫秒,而并发 277 毫秒。我的代码有问题吗?
并发:
private static void multiplyMatrixConcurent() {
result_concurent =new Matrix(rows, columns);
for (int i = 0; i < cell; i++) {
Runnable task = new MatrixMultiplicationThread(i);
Thread worker = new Thread(task);
worker.start();
}
}
private static class MatrixMultiplicationThread implements Runnable{
private int cell;
MatrixMultiplicationThread(int cell) {
this.cell=cell;
}
@Override
public void run() {
int row = cell / columns ;
int column = cell % columns;
for (int i = 0; i < rows; i++) {
double t1 = matrix.getCell(row, i);
double t2= matrix.getCell(i, column);
double temp= t1*t2;
double res = result_concurent.getCell(row, column) +temp;
result_concurent.setCell(res, row, column);
}
}
}
顺序:
private static void multiplyMatrixSequence() {
result_sequantial =new Matrix(rows, columns);
for (int i = 0; i < rows; i++) {
for (int j = 0; j <rows; j++) {
for (int k = 0; k < columns; k++) {
double t1=matrix.getCell(i,k);
double t2=matrix.getCell(k, j);
double temp= t1*t2;
double res = result_sequantial.getCell(i, j) + temp;
result_sequantial.setCell(res,i,j);
}
}
}
}
最佳答案
我没有看到任何明显的错误。您没有在发布的并发启动代码中将单元格设置为行*列,但我认为这是发布中的问题,而不是您运行的代码。
线程有开销。它们需要分配内存并需要额外管理 CPU 资源。如果线程数量适中并且硬件可以并行处理多个线程,那么您就赢了。然而,对于纯 cpu 绑定(bind)任务,拥有比处理元素更多的线程只是开销,没有任何好处。在本例中,您有 3600 个线程。我猜你有一个可以同时处理 2 到 8 个线程的处理器。您的线程数使处理器的能力相形见绌,因此速度变慢。
请注意,当线程执行磁盘或网络 I/O 等阻塞操作时,更多线程可以允许交错。这些语句也不适用于 GPU 计算情况,在这种情况下,即使内存访问也允许高效的线程交错。
顺便说一句,如果您的目标实际上是生成快速矩阵乘法,请使用现有库。这些库是由利用处理器缓存结构、专用硬件指令集和浮点的微妙细节来生成比临时编码人员可以生成的任何内容更快、更准确的库的人员开发的。
关于java - 多线程矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23594203/