java - 为什么使用比核心更大的执行器来加速并行编程?

标签 java parallel-processing executorservice parallelism-amdahl

我正在编写一个使用 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 上使用。您不需要多核处理器来执行多线程应用程序。

将线程想象成一个小进程,它由父程序创建并在完成后销毁。即使是单 CPU 计算机也可以同时运行多个线程。

ExecutorService 安排要执行的线程,并将运行与可用资源(包括核心)一样多的并行线程。

这是关于fixedThreadPool的文档

public static ExecutorService newFixedThreadPool(int nThreads)

Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all threads are active, they will wait in the queue until a thread is available. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks. The threads in the pool will exist until it is explicitly shutdown

你也可以试试workStealingPool

public static ExecutorService newWorkStealingPool()

Creates a work-stealing thread pool using all available processors as its target parallelism level.

关于java - 为什么使用比核心更大的执行器来加速并行编程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58629583/

相关文章:

c# - 如果在单独的方法中调用,为什么 Parallel.Invoke 会快得多?

java - 是否可以拥有一组线程池来共享大型线程池中的线程而不是创建新线程?

java - 音频流未在 Android webview fragment 中播放

java - 使用 3 个数学运算符的所有可能组合填充 2D 数组

.net - 终止 .NET 4 TPL 中的死锁任务

awk - 从多个进程 awk 写入同一文件的正确方法

java - 关闭时从可运行线程内停止计时器任务

java - 如何把一个无限任务(Runnable)暂时放弃

java - Jax.rs : What is the zero-length representation of an object?

java - 使用 Java SDK 列出 Amazon S3 中的所有对象