我需要创建一个仅返回一个数字的简单Java应用程序:估计的CPU性能。例如,当我在4核的机器上运行它时,我得到的数字大约是2核的机器的两倍。此应用应使用100%CPU持续几秒钟以进行测量。我真的不担心准确性。
我真的很惊讶,因为我找不到任何已经做到这一点的Java库。当然,还有其他语言的工具,但是在我的环境中,只有Java被批准。
我目前的想法是在代码中使用SciMark 2.0中的类并从多个线程运行它,但是此工具看起来很混乱(例如,类名以小写字母开头),我需要编写自定义代码才能运行这些线程并结合结果。
我能更好地解决这个问题吗?
答案 0 :(得分:1)
如果我对您的理解正确,那么您的目标是衡量系统性能而不是应用程序性能。
这是问题所在。系统性能不能降低到一个有意义的数字。实际上,系统性能甚至CPU性能都是多维的。
例如,一个占用大量内存的应用程序将在不同的机器上执行不同的操作,具体取决于CPU芯片的内存高速缓存大小和设计...以及内存速度。但是,如果应用程序是计算密集型的,那么性能将更多地取决于时钟速率和内核数。
然后,当核心数量很高和/或您有多个CPU芯片时,就会出现诸如NUMA单元和线程固定之类的问题。
这些和类似的问题是为什么试图测量独立于应用程序的原始CPU性能的基准测试在很大程度上已不受欢迎。 (MIPS原本是指每秒百万条(硬件)指令。现在通常被称为每秒神话指令……暗示该措施的虚伪性可预测实际应用程序性能)
答案 1 :(得分:0)
Java Mcrobenchmark Harness (JMH)是用于实现Java代码基准的工具包。
它测量吞吐量或平均时间;您可以使用它来估算CPU周期。
基本上,您需要使用@Benchmark
进行基准测试。
存储库中JMH usage samples很少。
在运行基准测试时,总是recommended让计算机单独运行,并且您应关闭所有其他应用程序(如果可能)。如果您的计算机运行的是其他应用程序,则这些应用程序可能会花费CPU时间,并且会给出错误的(较低的)性能数字。
如果您想进一步挖掘CPU性能(周期,缓存使用情况,说明等),则可能需要使用Linux perf
答案 2 :(得分:0)
这是执行我想要的最简单的代码。它尝试通过计算后续整数的平方根之和来估计多个线程的CPU性能。可以调整变量print(a) :
tensor([[-1.7739, 0.8073, 0.0472, -0.4084],
[ 0.6378, 0.6575, -1.2970, -0.0625],
[ 1.7970, -1.3463, 0.9011, -0.8704],
[ 1.5639, 0.7123, 0.0385, 1.8410]])
print(torch.argmax(a, dim=1))
tensor([1, 1, 0, 3])
以增加/减少基准长度。在我的计算机上,使用默认值大约需要7秒钟。
iterations
答案 3 :(得分:0)
Michal,感谢您的回答,我借用并添加了一些线程来帮助我诊断客户端的AIX计算机上的虚拟CPU性能问题。
import static java.util.stream.IntStream.rangeClosed;
public class Main {
public static void main(String[] args) {
if (args.length < 2) {
System.out.println("Usage: benchmark [million iterations] [maxThreads]");
return;
}
final int MILLION = 1_000_000;
final int iterations = Integer.parseInt(args[0]);
final int maxThreads = Integer.parseInt(args[1]);
for (int threads = 1; threads < maxThreads; threads++) {
long start = System.currentTimeMillis();
int count = iterations * MILLION / threads;
rangeClosed(1, threads).parallel()
.forEach(i -> rangeClosed(1, count).mapToDouble(Math::sqrt).sum());
System.out.println(String.format("Benchmark of %d M iterations on %d thread(s): %d ms", iterations, threads, System.currentTimeMillis() - start));
}
}
}