我们目前正试图通过在java应用程序中使用多线程来调整性能。我们有一个长期运行的串行任务,我们希望分裂成多CPU核心。
基本上,我们有100.000件事情要做的清单。
我现在的问题是,这样做是否更好:
选项1 (伪码):
for(i = 0; i < 100000; i++){
threadpool.submit(new MyCallable("1 thing to do"))
}
这将向线程池(当前LinkedBlockingQueue)的队列中添加100000个可运行项/可调用项。
还是做得更好:选项2 (伪码)
for(i = 0; i < 4; i++){
threadpool.submit(new MyCallable("25000 things to do"))
}
我们已经尝试了选项1,我们没有注意到任何性能的改善,尽管我们可以清楚地看到,多个线程正在疯狂地工作,并且使用了4个CPU核心。但我的感觉是,由于有许多任务,选项1中存在一些开销。我们还没有尝试选择2,但我的感觉是,它可以加快事情,因为有较少的开销。我们基本上将列表分成4个较大的块,而不是100000个单项。
对此有什么想法吗?
谢谢
发布于 2012-05-30 07:14:27
重要的是尽量减少上下文切换的数量,并最大限度地增加其计算所花费的每个任务的工作量。实际上,如果您的任务是计算的,超过物理CPU的数量是没有帮助的。如果您的任务实际上做了大量的I/O和I/O等待,那么您希望有很多这样的任务,所以在一个街区时总是有一堆“就绪”任务可用。
如果你真的有25000件事情要做,而且是计算,我可能会设置32个线程(比你有更多的CPU,但没有太多额外的开销),如果这些单位相对较小,我会把10-50个单位的工作分配给每个线程。
发布于 2012-05-30 07:09:07
您的分析是正确的:批次项目的成本将更低(内存、上下文切换和普通指令计数)--至少一般情况下是这样。
但是,随着单个任务的增加,这种情况越来越少--如果您已经将99 %的时间用于工作,而不是线程池开销或对象创建,那么您只能以这种方式对剩下的1%进行优化。
发布于 2012-05-30 07:11:02
这取决于你的用例。
就性能而言,我认为拥有更大块的工作要比更小的许多线程更好。上下文切换会更少,因此,您将能够节省CPU周期和RAM。
当任务数量较小时,这可能并不重要,但是是的,如果您有10000个线程,这确实很重要。
https://stackoverflow.com/questions/10811523
复制相似问题