【发布时间】:2017-08-26 22:19:22
【问题描述】:
读完article 后,我决定在笔记本电脑上查看。这个想法是创建大小为 [1..40] Mb 的数组,然后对其进行迭代 1024 次(例如,大小为 1 步长的数组将为 1024,步长为 2 mb 的数组将为 2048 等)。我的代码是:
public class L3CacheBenchmark {
@State(Scope.Benchmark)
public static class P {
@Param({
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
"21", "22", "23", "24", "25", "26", "27", "28", "29", "30",
"31", "32", "33", "34", "35", "36", "37", "38", "39", "40",
})
public int size;
}
@State(Scope.Thread)
public static class ThreadData {
byte[] array;
int len;
@Setup
public void setup(P p) {
array = new byte[p.size * 1024 * 1024];
len = array.length;
}
}
@Benchmark
public byte[] testMethod(ThreadData data) {
int step = (data.len / 1024) - 1;
for (int k = 0; k < data.len; k += step) {
data.array[k] = 1;
}
return data.array;
}
}
结果:
Benchmark (size) Mode Cnt Score Error Units
L3CacheBenchmark.testMethod 1 thrpt 100 310521,031 ± 1124,590 ops/s
L3CacheBenchmark.testMethod 2 thrpt 100 331853,495 ± 1124,547 ops/s
L3CacheBenchmark.testMethod 3 thrpt 100 311499,659 ± 745,414 ops/s
L3CacheBenchmark.testMethod 4 thrpt 100 290270,382 ± 8501,690 ops/s
L3CacheBenchmark.testMethod 5 thrpt 100 212929,246 ± 14847,931 ops/s
L3CacheBenchmark.testMethod 6 thrpt 100 315968,138 ± 4454,210 ops/s
L3CacheBenchmark.testMethod 7 thrpt 100 209679,904 ± 26050,365 ops/s
L3CacheBenchmark.testMethod 8 thrpt 100 60409,187 ± 212,548 ops/s
L3CacheBenchmark.testMethod 9 thrpt 100 221290,756 ± 28970,586 ops/s
L3CacheBenchmark.testMethod 10 thrpt 100 322865,687 ± 1545,967 ops/s
L3CacheBenchmark.testMethod 11 thrpt 100 263153,747 ± 18497,624 ops/s
L3CacheBenchmark.testMethod 12 thrpt 100 298683,205 ± 1277,032 ops/s
L3CacheBenchmark.testMethod 13 thrpt 100 180984,220 ± 26611,649 ops/s
L3CacheBenchmark.testMethod 14 thrpt 100 324815,938 ± 1657,303 ops/s
L3CacheBenchmark.testMethod 15 thrpt 100 264965,412 ± 9335,923 ops/s
L3CacheBenchmark.testMethod 16 thrpt 100 58830,825 ± 291,412 ops/s
L3CacheBenchmark.testMethod 17 thrpt 100 255576,829 ± 7083,025 ops/s
L3CacheBenchmark.testMethod 18 thrpt 100 324174,133 ± 2247,157 ops/s
L3CacheBenchmark.testMethod 19 thrpt 100 212969,202 ± 18204,625 ops/s
L3CacheBenchmark.testMethod 20 thrpt 100 295246,470 ± 1224,817 ops/s
L3CacheBenchmark.testMethod 21 thrpt 100 251762,642 ± 23405,100 ops/s
L3CacheBenchmark.testMethod 22 thrpt 100 323196,428 ± 2245,465 ops/s
L3CacheBenchmark.testMethod 23 thrpt 100 254588,338 ± 23845,090 ops/s
L3CacheBenchmark.testMethod 24 thrpt 100 53373,580 ± 252,183 ops/s
L3CacheBenchmark.testMethod 25 thrpt 100 213220,459 ± 20440,716 ops/s
L3CacheBenchmark.testMethod 26 thrpt 100 322625,597 ± 2076,341 ops/s
L3CacheBenchmark.testMethod 27 thrpt 100 293643,720 ± 5260,010 ops/s
L3CacheBenchmark.testMethod 28 thrpt 100 297432,240 ± 1186,920 ops/s
L3CacheBenchmark.testMethod 29 thrpt 100 169277,701 ± 25040,239 ops/s
L3CacheBenchmark.testMethod 30 thrpt 100 324230,899 ± 1579,103 ops/s
L3CacheBenchmark.testMethod 31 thrpt 100 193981,979 ± 12478,424 ops/s
L3CacheBenchmark.testMethod 32 thrpt 100 53761,030 ± 259,888 ops/s
L3CacheBenchmark.testMethod 33 thrpt 100 213585,493 ± 23543,671 ops/s
L3CacheBenchmark.testMethod 34 thrpt 100 325214,062 ± 1758,479 ops/s
L3CacheBenchmark.testMethod 35 thrpt 100 306652,634 ± 2237,818 ops/s
L3CacheBenchmark.testMethod 36 thrpt 100 297992,930 ± 1019,248 ops/s
L3CacheBenchmark.testMethod 37 thrpt 100 181671,812 ± 21984,441 ops/s
L3CacheBenchmark.testMethod 38 thrpt 100 321929,616 ± 1798,747 ops/s
L3CacheBenchmark.testMethod 39 thrpt 100 251587,385 ± 12292,670 ops/s
L3CacheBenchmark.testMethod 40 thrpt 100 49777,196 ± 227,620 ops/s
正如你所看到的,吞吐量是不同的,最显着的区别是对于大小为 8 倍数的数组:速度下降几乎是 4 倍。此外,例如,大小为 37 Mb 的阵列的速度几乎是 38 Mb 的两倍。对于我的发现,我没有找到任何合乎逻辑的解释。
附: CPU i7 4700mq 6 Mb 缓存:http://www.cpu-world.com/CPUs/Core_i7/Intel-Core%20i7-4700MQ%20Mobile%20processor.html
是什么导致了这种行为?
【问题讨论】:
-
您有问题吗?
-
大概的问题是“是什么导致了这种行为?”。
-
您应该通过
perf stat运行有趣的案例并进行比较。在笔记本电脑上,您可能应该确保 CPU 以固定的时钟频率运行,热节流会导致基准测试结果不一致。 -
感谢@OliverCharlesworth,我添加了问题。
-
有了这么大的一步,你几乎不需要检查你的缓存,只是在每个级别上强调几组。 TLB / page walk 很可能会成为您的瓶颈,因为您几乎每次访问都需要一个新页面。您也没有加热缓存,因此结果毫无意义。
标签: java caching memory jvm cpu-cache