Java 基于CPU核数的线程配置

Java 基于CPU核数的线程配置,java,multithreading,threadpool,cpu,akka,Java,Multithreading,Threadpool,Cpu,Akka,场景:我有一个示例应用程序,有3种不同的系统配置- - 2 core processor, 2 GB RAM, 60 GB HHD, - 4 core processor, 4 GB RAM, 80 GB HHD, - 8 core processor, 8 GB RAM, 120 GB HHD 为了有效地利用我的应用程序的H/W功能,我希望在应用程序级别配置线程的数量。然而,我希望只有在彻底了解系统功能之后才能这样做 是否有某种方法(system/modus/tool)来确定系统的能力,并参

场景:我有一个示例应用程序,有3种不同的系统配置-

- 2 core processor, 2 GB RAM, 60 GB HHD,
- 4 core processor, 4 GB RAM, 80 GB HHD,
- 8 core processor, 8 GB RAM, 120 GB HHD
为了有效地利用我的应用程序的H/W功能,我希望在应用程序级别配置线程的数量。然而,我希望只有在彻底了解系统功能之后才能这样做

是否有某种方法(system/modus/tool)来确定系统的能力,并参考它可以最佳服务的最大和最小线程数&而不会损失任何效率和性能。这样,我就可以只为我的应用程序配置那些能够充分发挥作用并为相应的硬件配置实现最佳性能的值

Edited1: 请任何人就如何为特定的h/w配置设置基线提出建议

Edited2:
为了使它更直接-希望了解/了解我可以阅读的任何资源/文章,以便在一般/整体级别上对线程的CPU管理有一些了解。

您可以获得JVM可用的处理器数量,如下所示:

Runtime.getRuntime().availableProcessors()

然而,不幸的是,根据可用处理器的数量来计算线程的最佳数量并非微不足道。这在很大程度上取决于应用程序的特性,例如,一个CPU绑定的应用程序的线程数超过处理器的数量是没有意义的,而如果应用程序主要是IO绑定的,则可能需要使用更多的线程。您还需要考虑系统上是否正在运行其他资源密集型进程


我认为最好的策略是根据经验确定每个硬件配置的最佳线程数量,然后在应用程序中使用这些数量。

要使用的最佳线程数量取决于几个因素,但主要取决于可用处理器的数量以及任务的cpu密集程度。提出以下形式化公式来估计最佳线程数:

N_threads = N_cpu * U_cpu * (1 + W / C)
其中:

  • N_线程是最佳线程数
  • N_cpu是可从
    Runtime.getRuntime().availableProcessor()获取的处理器数
  • U_cpu是目标cpu利用率(如果要使用全部可用资源,则为1)
  • W/C是等待时间与计算时间之比(CPU受限任务为0,慢I/O任务为10或100)
例如,在一个CPU受限的场景中,您将拥有和CPU一样多的线程(一些人主张使用这个数字+1,但我从来没有看到它有显著的不同)

对于较慢的I/O进程,例如web爬虫,如果下载页面的速度比处理页面的速度慢10倍,则W/C可能为10,在这种情况下,使用100个线程将非常有用

但是请注意,在实践中有一个上限(使用10000个线程通常不会加快速度,在使用正常内存设置启动它们之前,您可能会遇到OutOfMemory错误)

如果您对应用程序运行的环境一无所知,这可能是您所能得到的最佳估计。在生产环境中分析应用程序可能使您能够微调设置


虽然没有严格的关系,但您可能也对,它旨在测量并行化程序所能达到的最大速度。

使用该工具来监视线程。首先在程序中创建最小线程并查看其性能。然后增加程序中的线程数并再次分析其性能。这可能会对您有所帮助。

我的建议是提供配置和用于分配每台机器的线程数的命令行开关。如果用户/管理员没有明确地以不同的方式配置应用程序,请使用基于Runtime.getRuntime().availableProcessors()的启发式方法,如此处其他答案所示。我强烈建议不要基于排他启发式的线程到核心猜测,原因如下:

  • 大多数现代硬件正朝着越来越模糊的“硬件线程”类型发展:SMT模型,如英特尔的超线程和AMD的计算模块,使公式变得复杂(详情如下),在运行时查询这些信息可能会很困难

  • 大多数现代硬件都具有涡轮功能,可根据活动内核和环境温度调整速度。随着涡轮技术的改进,速度范围(ghz)也在增加。一些最新的Intel和AMD芯片的范围从2.6ghz(全核有源)到3.6ghz(单/双核有源),这与SMT相结合,意味着在以前的设计中,每个线程可以获得有效的1.6ghz-2.0ghz吞吐量。目前无法在运行时查询此信息

  • 如果您不能很好地保证您的应用程序将是目标系统上运行的唯一进程,那么盲目消耗所有cpu资源可能不会让用户或服务器管理员满意(取决于软件是用户应用程序还是服务器应用程序)

在运行时,如果不使用自己的多任务内核替换整个操作系统,就无法可靠地了解机器其余部分的运行情况。您的软件可以尝试通过查询进程和查看CPU负载等方式进行有根据的猜测,但这样做很复杂,并且用途仅限于特定类型的应用程序(您可能符合这些应用程序的条件),并且通常受益于或需要提升的或特权的访问级别

  • 现代病毒扫描器现在通过设置现代操作系统提供的特殊优先级标志来工作,例如,它们让操作系统告诉它们“系统空闲”。操作系统的决策依据不仅仅是CPU负载:它还考虑用户输入和可能由电影播放器设置的多媒体标志等。这对于大部分空闲任务来说是好的,但对于CPU密集型任务(如