【发布时间】:2015-04-23 13:31:43
【问题描述】:
如何使 CPU 利用率更稳定?
我想用 java 生成一个人工负载,它会强调 CPU 并消耗 RAM。资源消耗保持恒定很重要。此处的重点是 CPU。 RAM 是次要的。我选择 Java 是因为它几乎可以在所有平台上运行。我很想看看我的计算机上的这种负载是否会持续消耗每小时 20% 的 CPU 利用率,但在我的第二台计算机上可能是 30%。为了实现更高的 CPU 利用率和多核压力,程序使用多线程运行。
我已经阅读了 generate CPU load in Java 和 Artificial generation of cpu load in Java 在 stackoverflow 上的提问。
这是我的代码。我有一个类来控制线程和一个类来提供负载的线程。我选择计算阶乘来强调 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-Bit Server VM”。使用更紧凑的 JVM 是否有助于更稳定的 Java 资源消耗?
【问题讨论】:
-
不确定这样的程序是否可行。即使你设法写了一个,你如何确保其他外部因素保持不变?您如何确保操作系统不消耗任何 CPU 周期?您如何计算分析器消耗的 CPU 周期?
-
您使用的是什么版本的 Java?
-
@bot 我打印出每个线程的 while 循环每次迭代的毫秒数。大多数情况下,执行时间仅相差 1-3 毫秒。然后那里有一些小的巨大的跳跃。我试图以更高的优先级运行线程,但仍然如此。我玩弄了睡眠时间和阶乘的参数,以便 cpu 利用率不会太高,操作系统仍然可以获得资源。但我不知道峰值是来自 java 本身还是另一个进程“窃取”了 cpu 时间。我有一个 i7,有四个核心,总共 8 个虚拟。
-
@SleimanJneidi 我正在使用 Java 6.0.240.7