How can I get the CPU utilisation more constant?
I would like to generate an artificial load with java which stresses the CPU and consumes RAM. It is important that the resource consumption stays constant. The focus hereby is on the CPU. RAM is secondary. I chose Java since it can run on almost every platform. I am interested to see if this load on my computer for example constantly consumes 20% of the CPU utilization per hour, but on my second computer maybe 30%. To achieve higher CPU utilization and stress multiple cores the program runs with multiple threads.
I have already read generate CPU load in Java and Artificial generation of cpu load in Java asked on stackoverflow.
Here is my code. I have one class to control the threads and one class for the threads providing the load. I chose to calculate factorial to stress 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) {}
}
}
}
My measurement tool measures every 5min (not a sample but the average utilization in this period). So minimal variation can be tolerated. But still, sometimes it shows strong peaks I cannot explain.
Question one: Do you know why my CPU utilization could have such strong peaks?
Question two: What programming techniques can I use to minimize CPU utilization deviation?
[Update 04-30-2015]
My assumption to question one cause: Hyper Threading
I have a HP laptop i7 quad-core with hyper threading (task manager shows 8 virtual cores). The measuring tool I use has a hyper threading correction and shows the actual resources consumed. Whereas, this is a guess, VisualVM only measures the virtual core consumption!? I tried to deactivate hyper threading in BIOS to proof the correctness of my assumption. But thanks to HP this option is not available under configuration in BIOS. What do you think, is hyper threading the cause of the measurement deviation?
Alternative approach: different JVM
I am using the standard JVM "Java HotSpot(TM) 64-Bit Server VM". Would useing a more compact JVM contribute to a more stable Java resource consumption?