最近我正在编写一些微基准代码,所以我必须打印出JVM行为以及我的基准信息.我用
-XX:+PrintCompilation
-XX:+PrintGCDetails
Run Code Online (Sandbox Code Playgroud)
以及获取JVM状态的其他选项.对于基准信息,我只是使用System.out.print()方法.因为我需要知道我打印的消息的顺序和JVM输出.
当我在控制台中打印它们时,我可以得到很好的结果,虽然JVM输出有时会撕掉我的消息,但由于它们处于不同的线程中,因此它是可以理解和可接受的.
当我需要做一些批次的基准,我想redirect the output into a file用pipe (> in Linux system),并使用Python从文件中获取结果,并进行分析.
这是问题所在:
The JVM output always overlapped with the messages I printed in the Java application. 它破坏了消息的完成.
知道如何应对这种情况吗?我需要both the JVM output and application output in the same place in order to preserve the sequence because it is important. And they do not overlap on each other so I don't lose anything.
在Ulrich Drepper的论文中,每个程序员应该了解内存,第三部分:CPU缓存,他显示了一个图表,显示了"工作集"大小与每个操作消耗的cpu周期之间的关系(在这种情况下,顺序读取).并且图中有两个跳转,表示L1缓存和L2缓存的大小.我编写了自己的程序来重现c中的效果.它只是简单地从头到尾顺序读取一个int []数组,我尝试了不同大小的数组(从1KB到1MB).我将数据绘制成图形并且没有跳跃,图形是直线.
我的问题是:
顺便说一句,我在linux中这样做.
感谢Stephen C的建议,这里有一些额外的信息:这是我的代码:
int *arrayInt;
void initInt(long len) {
int i;
arrayInt = (int *)malloc(len * sizeof(int));
memset(arrayInt, 0, len * sizeof(int));
}
long sreadInt(long len) {
int sum = 0;
struct timespec tsStart, tsEnd;
initInt(len);
clock_gettime(CLOCK_REALTIME, &tsStart);
for(i = 0; i < len; i++) {
sum += arrayInt[i];
}
clock_gettime(CLOCK_REALTIME, &tsEnd);
free(arrayInt);
return (tsEnd.tv_nsec - tsStart.tv_nsec) / len;
}
Run Code Online (Sandbox Code Playgroud)
在main()函数中,我尝试过从1KB到100MB的数组大小,仍然相同,每个元素的平均耗时为2纳秒.我认为时间是L1d的访问时间.
我的缓存大小:
L1d == 32k
L2 == 256k
L3 == …
当我用参数启动JVM时
-XX:+PrintCompilation
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
60 1 java.lang.String::hashCode (55 bytes)
74 2 sun.nio.cs.UTF_8$Encoder::encode (361 bytes)
Run Code Online (Sandbox Code Playgroud)
第一列是以毫秒为单位的时间戳,当打印日志时,我想将此时间戳与返回的值进行比较ManagementFactory.getRuntimeMXBean().getUptime():
long jvmUpTime = ManagementFactory.getRuntimeMXBean().getUptime();
Run Code Online (Sandbox Code Playgroud)
要么
long jvmStartTime = ManagementFactory.getRuntimeMXBean().getStartTime();
Run Code Online (Sandbox Code Playgroud)
但我的结果是这样的:
[62:log from Java code]
103 5 benchmark.AbstractBenchmarkST::benchmark (82 bytes)
[62:log from Java code]
Run Code Online (Sandbox Code Playgroud)
似乎它们之间有大约40毫秒的差异,这使得两个时间戳无法比拟.任何想法如何处理这个?