我有一个在四核 Intel i7 上运行的多线程程序。当我执行时Runtime.getRuntime.availableProcessors()
,我得到 8,并且我知道在这个 CPU 上可以使用超线程。
但是,当我创建线程时,4 个线程的 CPU 级别为 100%(即非零),这意味着 4 个线程未使用。有没有办法在 Java 中启用超线程?
我有一个在四核 Intel i7 上运行的多线程程序。当我执行时Runtime.getRuntime.availableProcessors()
,我得到 8,并且我知道在这个 CPU 上可以使用超线程。
但是,当我创建线程时,4 个线程的 CPU 级别为 100%(即非零),这意味着 4 个线程未使用。有没有办法在 Java 中启用超线程?
所有现代 JVM 都使用本机线程这一事实启用了超线程,因此这是一个 OS/CPU 配置设置。
然而,超线程不会给你额外的内核,它允许你拥有的四个 cpu 的细粒度分时。也就是说,当一个线程停止时,比如等待一页内存流入缓存,然后另一个线程可以突然介入并使用部分 CPU。由于更复杂的调度要求,它使 CPU 内核的大小增加了大约 10%,并且不会使所有应用程序受益。
如果您已经用四个线程最大化了四个 cpu,那么可以通过打开或关闭超线程来实现。这只是意味着这些线程正在运行,没有太多阻塞。
Java 报告 8 核 CPU 而不是 4 核的原因是因为操作系统告诉 Java CPU 有 8 个核。操作系统认为,因为操作系统被告知要像 8 核 CPU 一样调度线程,这使得向操作系统添加对超线程的支持变得更加简单。操作系统像以前一样继续管理线程,忽略了超线程的大部分内部工作,并让 CPU 在部分 cpu 可用时管理程序集的低级调度。
使用以下命令
$ lscpu
输出可用于确定内核的实际数量以及是否启用了超线程。
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 32
On-line CPU(s) list: 0-31
Thread(s) per core: 2
Core(s) per socket: 8
Socket(s): 2
NUMA node(s): 2
Vendor ID: GenuineIntel
CPU family: 6
Model: 45
Stepping: 7
CPU MHz: 2399.995
BogoMIPS: 4799.35
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
可以实现的实际并行度将是(插槽数)X(每个插槽的核心数)X(每个核心的线程数)。要确定您的处理器是否是超线程的,您可以使用 Threads per core 参数。