2016-08-07 50 views
0

我最近碰到这个问题就来了一个评估:线程池的大小应该达到最大性能?

ExecutorService threadpool = Executors.newFixedThreadPool(N); 

for(Runnable task : tasks){ 
    threadpool.submit(task); 
} 

每个任务花费的计算为25%和75%执行I/O。假设我们正在研究四核机器(无超线程),线程池N的大小应该是多少以达到最大性能而不浪费线程? (假设我们有无限的I/O容量)

我猜测16是因为机器有无限的I/O意味着我们可以完全专注于CPU。每个任务在运行时使用四分之一的CPU。这意味着,我们可以运行四个任务来饱和一个CPU内核,并使四核机器上的N = 16。

更新:此题的选项分别为2,4,5,6,7,8,12和16

+3

你的答案是什么,你是怎么想出来的,你为什么不认为这是正确的答案? – Andreas

+0

我的回答是16,因为这台机器有无限的I/O意味着我们可以完全专注于CPU。每个任务在运行时使用四分之一的CPU。这意味着,我们可以运行四个任务来饱和一个CPU内核,并使四核机器上的N = 16。 – Mickey

+0

听起来像是对我的正确答案。 – Andreas

回答

0

你是正确的,你应该考虑你的饱和核。不过,最好的答案将超过16个。如果你只有16个线程,那么CPU的需求就不会完全对齐,这样你所有的内核都会一直在使用。

所以最好的答案是> 16,也足够小,不会显著提高个人任务完成时间,并处显著线程转换成本,或浪费一大堆的内存。

如果你在课堂上学到了这一点,那么你的教授可能会给你乘数作为“经验法则”。他会期待你记住它并将它应用到这里。

我通常使用average_demand = 2 * num_cores,所以会选择32个线程。这在大多数情况下运作良好。当平均CPU需求是核心数量的两倍时,核心利用率将接近100%。

而且,在这种情况下,每个任务的CPU部分只得到平均1/2的核心,因此它需要两倍的时间......但这样的任务完成时间只有13它是工作的只有25% %超过最佳。

2倍的默认,我用差不多比最佳人数始终较高,但它也几乎总是足够低,不征收额外显著开销。如果你知道你的任务的CPU限制很大,那么你可以自信地减少这个数字。

如果你真的想找到最佳值,那么你可以测量它,但是当你在正确的范围内它不会产生很大的差异。

-

P.S注:“average_demand”我上面使用是芯,这将是在使用中在任何时候给定N个线程和N个核的预期数量。

1

虽然这个问题没有严格的对错,主观好的是:

32个线程

你必须考虑从概率上。 现在让我们考虑一个CPU核心和独立线程:

一个线程在任何给定时间有25%的机会做计算。 如果你有2个独立的线程(概率事件),至少有一个CPU做一些工作的概率不是50%,而是7/16(43.75%)。(如果您对此不确定,则应刷新其中一些probability skills)。

你可能会看到这是怎么回事。对于P为100%,线程数必须是无限的。所以我们必须做出有根据的猜测:4个线程的P为〜68%,8个线程为〜90%。增加数量现在真的没有什么效果,所以我们定在8点。这是一个核心。我们有4个CPU核心,所以我们可以乘以4,我们得到最终答案:32.