编程语言
首页 > 编程语言> > java-Fork / Join:最佳线程数

java-Fork / Join:最佳线程数

作者:互联网

任务定义:我需要映射一个很大的数组.例如,让我们成为afindMax()函数.因此,任务是尽可能快地执行此操作(这意味着并行执行).

硬件:我有8个核心,每个核心都有2个超线程

public static void main(String... args) {
   int maxThreadAmount = Runtime.getRuntime().availableProcessors(); // GET 8
}

解决方案1:只是为了将任务运行到N个线程中.其中N应该是某个最佳数.

问题#1:是下一个权利:int OptimalThreadAmount = maxThreadAmount-1吗?

解决方案2:我想通过Fork / Join框架解决该问题.如果输入太大,则每个任务会分成两个并行的子任务.所以我会得到类似

                   Find Max 
                   [array]    <---- +1 pending thread
                   /        \
                  /          \
           Find Max        Find Max
          [1/2 array]      [1/2 array]  <-------- +2 pending threads
            /      \          /   \
           /        \        ..   ..
      Find Max      Find Max
     [1/4 array]    [1/4 array]      <-------- +4 four pending threads
       /       \        / \
      /         \      ..  ..
    Find Max    Find Max
    [1/8 array] [1/8 array]  <----------- +8 active threads

问题2:考虑到使用Fork / Join算法,我们将获得一堆待处理线程,最佳线程数是多少?

解决方法:

最佳线程数应在计算机具有的内核数附近.但是,请记住,将工作负载分为两个子任务时,应计算一个任务,而应将另一个分支.这意味着拆分时仅创建一个额外的线程.

大多数分叉/联接算法都伴随有顺序截止.当您达到特定条件时(例如,用于确定大小为1000的最大值的数组),您将切换到顺序算法(即,逐个检查元素).因此,如果我猜测最佳情况来计算您的问题,我会说,目前您已经分裂了14次,产生了16个线程,然后切换到顺序算法.这意味着每个内核都有一个正在运行的线程,因此将保持繁忙状态. (此猜测假设您的内核具有超线程之类的功能,如果没有,我会说8个线程).

另外,不建议对您给出的方程式进行修正(int OptimalThreadAmount = maxThreadAmount-1),因为这意味着您假设计算机不做任何其他事情,并且可以使用所有线程.

我的猜测是,当使用顺序中断时,您的最佳性能将约为16个线程(当没有其他进程在使用您的计算机时).您可以自己进行测试,这始终是最好的方法.您要研究的问题是,当您开始产生大量线程时,每个线程的开销将变得显而易见.

附言:使用fork / join的优点是,您的代码将能够根据计算机具有的内核数进行很好的扩展.更多的内核意味着更多的线程将并行运行.这意味着您的线程调度程序可以将更多线程用于工作.

编辑
那么对于给定数量的内核,我应该使用的最佳截止频率是多少?

好吧,我的猜测是您将实现一个fork / join算法.您有一个连续的截止时间(即,一旦我的输入数组的大小为x,就停止分叉并加入).

当您知道必须在哪个系统上运行算法时,便可以运行基准测试.

对于从x到y的连续截止,您可以运行代码.每次迭代都测量应用算法需要多长时间.这样,您将看到最适合您的配置.

再说一次,如果您想要一种快速而肮脏的方法,可以执行以下操作:

具有p核的机器,输入数组的大小为s:

Sequential cutoff = s/8

但是,如前所述,我强烈建议不要这样做.

标签:performance,multithreading,concurrency,fork-join,java
来源: https://codeday.me/bug/20191029/1960019.html