可能重复:
Would a multithreaded Java application exploit a multi-core machine very well?
我的双核机器(Windows XP 32位环境)上有一个简单易懂的Java线程
public static void main(String[] strs) {
long j = 0;
for(long i = 0; i<Long.MAX_VALUE; i++)
j++;
System.out.println(j);
}
我的期望是它会坚持使用单个CPU来充分利用高速缓存(因为在循环中我们继续使用本地变量j运行,因此一个CPU工具将是100%而另一个将是相当多的闲。 令我惊讶的是,在线程启动后,两个CPU的使用率都在40%~60%左右,而一个CPU的利用率略高于另一个CPU。
我的问题是,是否有任何操作系统负载均衡机制在检测到不平衡时启动?在我的情况下,Windows操作系统可能发现一个CPU几乎达到100%而另一个几乎处于空闲状态,因此它会定期将线程重新安排到另一个CPU?
#EDIT1 我找到了一个可能的解释: http://siber.cankaya.edu.tr/ozdogan/OperatingSystems/ceng328/node130.html
答案 0 :(得分:3)
当OS执行线程时,它会运行每个线程一段时间(比如10-20ms),然后保存线程的状态,并寻找其他线程来运行。
现在,尽管您在查看CPU利用率图表时可能会想到,操作系统实际上运行的程序比程序中的程序要多得多。有些线程运行UI循环,线程在I / O上等待,线程运行后台服务等。大多数线程花费大部分时间来阻止等待某些东西。
我之所以谈论这个,是因为从操作系统的角度来看,情况比它看起来更复杂。有很多线程在做很多事情,操作系统试图在它们之间切换。假设您想要实现一种启发式方法,如果一个线程最后一次耗尽其整个量程,那么操作系统将努力将其安排到同一个核心。操作系统需要跟踪并考虑更多信息,优化的成功可能取决于许多难以预测的因素。
此外,在实践中将线程关联到核心的好处通常可以忽略不计,因此操作系统不会尝试自动执行此操作。相反,他们公开了一个功能,允许开发人员明确说明特定线程应该与核心关联,然后操作系统将尊重该决定。
这似乎是一个合理的权衡:如果你的线程在关注核心时表现更好,那就请求操作系统这样做。但是,操作系统不会费心试图为你解决这个问题。
答案 1 :(得分:1)
正如你所提到的,操作系统会弹回线程。以下本机代码也如您所述。
int main( int argc, char** argv )
{
while( true );
return 0;
}
如果你看一下这个过程,它一直是25%(使用四核),但Windows 7的资源监视器显示4个核心中没有一个是100%的常数,即使核心0处于使用率高于其他人。
核心之间的cpu may share缓存,因此这种行为并不意味着没有使用缓存。
答案 2 :(得分:0)