如何让CPU利用率更加稳定?
我想用java生成一个人工负载,它会强调CPU并消耗RAM。资源消耗保持常数非常重要。因此,重点在于CPU。 RAM是次要的。我之所以选择Java,因为它可以在几乎所有平台上运行。我有兴趣看看我的计算机上的这种负载是否经常消耗每小时CPU利用率的20%,但在我的第二台计算机上可能是30%。为了实现更高的CPU利用率并强调多个内核,程序可以运行多个线程。
我已经在stackoverflow上阅读了generate CPU load in Java和Artificial generation of cpu load in Java。
这是我的代码。我有一个类来控制线程,一个类用于提供负载的线程。我选择计算阶乘来压力CPU。
package loadPackage;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class LoadController {
public static void main(String[] args) {
int threads = 16;
int runlength = 100000;
long time;
try {
runlength = Integer.parseInt(args[0]);
} catch (Exception e) {
System.out.println("Only integer allowed!");
}
time = System.currentTimeMillis() + runlength;
ExecutorService executor = Executors.newFixedThreadPool(threads);
for (int i = 0; i < threads; i++) {
Runnable worker = new Workload(time);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
}
}
package loadPackage;
import java.math.BigInteger;
public class Workload implements Runnable {
private long time;
public Workload(long time) {
this.time = time;
}
public void run() {
while (System.currentTimeMillis() < time) {
BigInteger fact = BigInteger.valueOf(1);
for (int i = 1; i <= 6000; i++) {
fact = fact.multiply(BigInteger.valueOf(i));
}
try {
Thread.sleep(200);
}
catch (Exception localException1) {}
}
}
}
我的测量工具每5分钟测量一次(不是样本,而是这个时期的平均利用率)。因此可以容忍最小的变化。但是,有时它显示出我无法解释的强烈峰值。
问题一:您知道为什么我的CPU利用率会如此强劲吗?
问题二:我可以使用哪些编程技术来最小化CPU利用率偏差?
[2015年4月30日更新]
我怀疑一个原因:超线程我有一台带超线程的HP笔记本电脑i7四核(任务管理器显示8个虚拟内核)。我使用的测量工具具有超线程校正功能,并显示实际消耗的资源。然而,这是猜测, VisualVM仅测量虚拟核心消耗 !?我试图在BIOS中停用超线程来证明我的假设的正确性。但是由于HP,此选项在BIOS中的配置下不可用。你怎么看,超测量偏差的原因是什么?
替代方法:不同的JVM 我使用标准JVM“Java HotSpot(TM)64位服务器VM”。使用更紧凑的JVM会有助于更稳定的Java资源消耗吗?
答案 0 :(得分:0)
CPU利用率由操作系统管理,因此AFAIK无法将java线程“锁定”到特定处理器(这将导致持续利用)。
当你在linux系统上打开htop
时,你会看到这一点。线程将像板球一样跳过你的cpus。
我从未设法在java
中实现这种持续利用,仅在C(++)
。
答案 1 :(得分:0)
我建议您在此过程中启动visual vm。您将能够跟踪GC活动。如果您看到GC峰值消耗的CPU时间与您之前看到的一样,那么您可以确定原因。
答案 2 :(得分:0)
我知道这有点旧线程,但如果您仍然感兴趣,请查看https://github.com/OpenHFT/Java-Thread-Affinity处的OpenHFT Java线程关联库。我已经用它来将Java线程固定到给定的内核,并为某些应用程序提供良好的性能(CPU使用率)。
正如作者博客(http://vanillajava.blogspot.com/2011/12/thread-affinity-library-for-java.html)中提到的具有隔离内核(您可以在启动时传递isolcpus)也会有所帮助。