在Java中生成CPU负载

15

我正在进行一些吞吐量测试。我的应用程序需要:

  1. 从JMS中读取数据
  2. 进行一些处理
  3. 将数据写入JMS

我的目标是模拟第二个步骤,“进行一些处理”。也就是说,在转发事件之前,引入延迟并占用CPU一定时间(例如500毫秒)。

一个朴素的方法是使用 Thread.sleep(500)。这会引入正确的执行延迟,但不会使CPU得到锻炼。

计算斐波那契数列是一个选择。有人使用过任何有趣的技术来保持CPU在给定时间内保持繁忙状态吗?

理想的特点应该是:

  • 执行各种指令,而不是(例如)只是在循环中旋转等待
  • 不是HotSpot VM将被优化为消失的东西
  • 有一种简单的方法可以调整处理时间长度(显然,由于硬件的不同,完成时间会有所不同)

你能进一步解释为什么利用CPU是必要的,但仅仅使用Thread.sleep()睡眠不合适吗? - matt b
我不确定你所说的“锻炼CPU”具体是什么意思,以及为什么你需要这样做。你能否详细解释一下?你究竟在测试什么?从我所看到的情况来看,这可能是“某些处理”、读/写JMS或向此设备发送数据中的一种。谢谢。 - Szymon Rozga
睡眠不适合。我需要JMS操作在真实的CPU条件下进行。空闲的CPU可能会给我虚高的JMS性能;我需要CPU处于“真实”繁忙状态,以便我的JMS测量结果准确。 - Air
5个回答

23

你可以尝试一些简单的东西,比如

private static void spin(int milliseconds) {
    long sleepTime = milliseconds*1000000L; // convert to nanoseconds
    long startTime = System.nanoTime();
    while ((System.nanoTime() - startTime) < sleepTime) {}
}

测试:

public static void main(String[] args) {
    final int NUM_TESTS = 1000;
    long start = System.nanoTime();
    for (int i = 0; i < NUM_TESTS; i++) {
        spin(500);
    }
    System.out.println("Took " + (System.nanoTime()-start)/1000000 +
        "ms (expected " + (NUM_TESTS*500) + ")");
}

我的输出:

$ java SpinTest
Took 500023ms (expected 500000)

所以这个循环没有被优化掉(是的,我为了测试这个问题让我的CPU跑满了八分钟:))。


1
这将有效,直到下一个版本的HotSpot对其进行优化... - toolforger

6

通过调用Cipher.update()对字符串进行加密(循环中)。 加密算法本质上非常难以优化。唯一的问题在于需要执行一些非平凡的设置。我将此答案标记为社区wiki,以便最近编写它的人可以填写它。


4
创建一个非常大的随机对象集合,然后交替调用Collections.shuffle()Collections.sort()
我使用Jakarta Commons Lang生成随机字符串来进行洗牌/排序。

0

还有另一种可能会用得到的东西:

        long start  = System.currentTimeMillis();
        long count = 0l;
        for(long x=0;x<Integer.MAX_VALUE ;x++){
            count+=1;
        }
        long end = System.currentTimeMillis();
        System.out.println(end-start +" ms");

0
创建一个矩阵并进行一些矩阵操作。
通过改变矩阵的大小,您可以轻松地调整它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接