4

我有一个程序可以并行运行(全天)任务(要执行的任务中没有 I/O),所以我习惯于Executors.newFixedThreadPool(poolSize)实现它。

最初我将其设置poolSizeRuntime.getRuntime().availableProcessors(),但我有点担心要使用所有可用的内核,因为在同一台 PC(32 个内核)上运行着其他进程。

特别是我有十个其他 JVM 运行相同的程序(在不同的输入数据上),所以我有点担心在可用内核之间切换线程方面可能会有很多开销,这可能会减慢整体计算速度.

我应该如何决定每个程序/JVM 的池大小?

此外,在我的 PC 中,还有其他进程一直在运行(防病毒、备份等)。我也要考虑这些吗?

4

4 回答 4

1

任何建议都将取决于您的具体情况。32 个内核上的 10 个 JVM 建议每个 3 个线程(忽略垃圾收集线程、计时器任务等......)

您还有其他任务正在运行。调度程序将确保它们正在运行,但它们是否必须响应?比 JVM 响应更快?如果您正在运行 Linux/Unix,那么您还可以利用优先级(通过nice)来确保特定进程不会占用 CPU。

最后,您正在运行 10 个 JVM。这会导致分页吗?如果是这样,那将会很慢,并且您最好运行更少的 JVM 以避免消耗太多内存。

只需确保您的关键变量是公开且可配置的,并测量各种场景以找到最佳场景。

于 2013-01-14T17:26:04.323 回答
1

我应该如何决定每个程序/JVM 的池大小?

您想要的线程数将使您接近 99% 的利用率,仅此而已。

平衡工作的最简单方法是让进程运行一次,同时处理多个文件并仅使用一个线程池。如果您需要通过命令行启动文件,您可以将进程设置为服务。

如果由于某种原因这是不可能的,您将需要猜测线程池应该缩小多少。尝试运行一个进程并查看利用率。如果一个是 40%,那么我怀疑 10 个进程被 400% 过度使用。即,您可以将池大小减少 4 倍。

于 2013-01-14T17:26:08.363 回答
0

不幸的是,这是一件很难知道的事情,因为程序通常不知道同一个盒子上还有什么或可能发生什么。

“简单”的出路是使池大小可配置。这允许控制程序/盒子的用户决定为您的程序分配多少线程(大概使用他们对盒子的一般工作负载的了解)。

一个更复杂的解决方案是尝试以编程方式确定盒子的当前工作量并从中适当地选择池大小。此解决方案的功效取决于您确定工作负载的准确程度以及随着时间的推移可能会发生的变化。

于 2013-01-14T17:26:34.837 回答
0

尝试 grepping 进程,检查顶部/任务管理器和性能监视器,以验证此实现是否确实影响了您的机器。

这篇文章似乎包含有关您尝试实现的有趣信息:http: //www.ibm.com/developerworks/library/j-jtp0730/index.html

于 2013-01-15T11:49:25.110 回答