最佳线程数应在计算机具有的内核数附近.但是,请记住,将工作负载分为两个子任务时,应计算一个任务,而应将另一个分支.这意味着拆分时仅创建一个额外的线程.
大多数分叉/联接算法都伴随有顺序截止.当您达到特定条件时(例如,用于确定大小为1000的最大值的数组),您将切换到顺序算法(即,逐个检查元素).因此,如果我猜测最佳情况来计算您的问题,我会说,目前您已经分裂了14次,产生了16个线程,然后切换到顺序算法.这意味着每个内核都有一个正在运行的线程,因此将保持繁忙状态. (此猜测假设您的内核具有超线程之类的功能,如果没有,我会说8个线程).
另外,不建议对您给出的方程式进行修正(int OptimalThreadAmount = maxThreadAmount-1),因为这意味着您假设计算机不做任何其他事情,并且可以使用所有线程.
我的猜测是,当使用顺序中断时,您的最佳性能将约为16个线程(当没有其他进程在使用您的计算机时).您可以自己进行测试,这始终是最好的方法.您要研究的问题是,当您开始产生大量线程时,每个线程的开销将变得显而易见.
附言:使用fork / join的优点是,您的代码将能够根据计算机具有的内核数进行很好的扩展.更多的内核意味着更多的线程将并行运行.这意味着您的线程调度程序可以将更多线程用于工作.
编辑
那么对于给定数量的内核,我应该使用的最佳截止频率是多少?
好吧,我的猜测是您将实现一个fork / join算法.您有一个连续的截止时间(即,一旦我的输入数组的大小为x,就停止分叉并加入).
当您知道必须在哪个系统上运行算法时,便可以运行基准测试.
对于从x到y的连续截止,您可以运行代码.每次迭代都测量应用算法需要多长时间.这样,您将看到最适合您的配置.
再说一次,如果您想要一种快速而肮脏的方法,可以执行以下操作:
具有p核的机器,输入数组的大小为s:
Sequential cutoff = s/8
但是,如前所述,我强烈建议不要这样做.