问题描述
有人可以帮我理解JVM如何在可用的CPU内核之间传播线程吗?在这里,我的想法是如何工作但是请纠正我。
Can somebody help me to understand how JVM spread threads between available CPU cores? Here som my vision how it is work but pls correct me.
所以从开始:当计算机启动时然后引导线程(通常在处理器0中的核心0中的线程0) )启动从地址0xfffffff0获取代码。所有其余的CPU /内核都处于特殊的睡眠状态,称为Wait-for-SIPI(WFS)。
So from the begining: when computer is started then bootstrap thread (usually thread 0 in core 0 in processor 0) starts up fetching code from address 0xfffffff0. All the rest CPUs/cores are in special sleep state called Wait-for-SIPI(WFS).
然后在加载操作系统后,它开始管理进程并在CPU之间安排它们/ core通过高级可编程中断控制器(APIC)发送特殊的处理器间中断(IPI),称为SIPI(启动IPI),用于WFS中的每个线程。 SIPI包含该线程应该从该地址开始获取代码的地址。
Then after OS is loaded it starts managing processes and schedule them between CPU/cores sending a special inter-processor-interrupt (IPI) over the Advanced Programmable Interrupt Controller (APIC) called a SIPI (Startup IPI) to each thread that is in WFS. The SIPI contains the address from which that thread should start fetching code.
因此,例如OS通过在内存中加载JVM代码并将其中一个CPU内核指向其中来启动JVM地址(使用上述机制)。之后,作为具有自己的虚拟内存区域的单独OS进程执行的JVM可以启动多个线程。
So for example OS started JVM by loading JVM code in memory and pointing one of the CPU cores to its address (using mechanism described above). After that JVM that is executed as separate OS process with its own virtual memory area can start several threads.
所以问题是:如何?
JVM是否使用与OS相同的机制,并且在操作系统提供给JVM的时间片中,可以将SIPI发送到其他核心并指向应在单独线程中执行的任务的地址?如果是,那么如何恢复操作系统可以在此核心上执行的原始程序?
Does JVM use the same mechanism as OS and during time slice that OS gave to JVM can send SIPI to other cores and point the to address of the tasks that should be executed in a separate thread? If yes then how is restored the original program that could be executed by OS on this core?
假设这是不正确的视图,假设这个涉及其他CPU的任务/ cores应该通过操作系统进行管理。过度我们可以中断在其他核心上并行运行的某些OS进程的执行。因此,如果JVM想要在其他CPU /核心上启动新线程,则会进行一些OS调用并将要执行的任务的地址发送到OS。 OS计划执行与其他程序一样,但执行应该在同一进程中,以便能够访问与其余JVM线程相同的地址空间。
Assume that it is not correct vision as suppose that this tasks of involving other CPUs/cores should be managed via OS. Overwise we could interrupt execution of some OS processes running in parallel on other cores. So if JVM wants to start new thread on other CPU/core it makes some OS call and send address of the task to be executed to the OS. OS schedule execution as for other programs but with different that this execution should happen in the same process to be able to access the same address space as the rest JVM threads.
怎么做?有人可以更详细地描述它吗?
How is it done? Can somebody describe it in more details?
推荐答案
操作系统默认管理和调度线程。 JVM对操作系统进行正确调用以实现此目的,但不会涉及。
The OS manages and schedule threads by default. The JVM makes the right calls to the OS to make this happen, but doesn't get involved.
JVM使用操作系统,它不知道实际发生了什么。
The JVM uses the OS, it has no idea what actually happens.
每个进程都有自己的虚拟地址空间,再次由操作系统管理。
Each process has its own virtual address space, again managed by the OS.
我有一个使用的库JNA在Linux和Windows上包装setaffinity。您需要这样做,因为线程调度由操作系统而不是JVM控制。
I have a library which uses JNA to wrap setaffinity on Linux and Windows. You need to do this as thread scheduling is controlled by the OS not the JVM.
注意:在大多数情况下,使用亲和力a)不't help或b)没有你想象的那么多。
Note: in most cases, using affinity either a) doesn't help or b) doesn't help as much as you might think.
我们用它来减少大约40到100微秒的抖动,这种情况并不常见,但往往足以影响我们的表现形象。如果您希望99%的ile延迟尽可能低,则在微秒范围内,线程亲和力至关重要。如果100个请求中有1个可以延长1毫秒,那我就不会打扰了。
We use it to reduce jitter of around 40 - 100 microseconds which doesn't happen often, but often enough to impact our performance profile. If you want your 99%ile latencies to be as low as possible, in the micro-second range, thread affinity is essential. If you are ok with 1 in 100 requests taking 1 ms longer, I wouldn't bother.
这篇关于JVM如何在CPU内核之间传播线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!