我做了一个基准测试,它具有读取高速缓存行以测量MPKI(每千条指令的高速缓存未命中)的功能,以及syscall
,它也具有相同的功能,但是以不同的方法(vmalloc)实现。我希望两个级别的MPKI都一样,但是用户MPKI比内核MPKI太高了。
我当前正在使用linux-4.14.84
,并使用performance monitoring counter
测量缓存未命中和指令计数。由于slap大小的限制,在syscall中,我使用vmalloc
代替kmalloc。
因此,这是用于创建和访问缓存行的简单代码。
void do_test(void *cache)
{
for (n = 0; n < 100000; n++) {
for (i = 0; i < CACHE_LINE_NUM; i++) {
offset = cache + offset;
}
}
}
void init_cache(void *cache, int size, int stride)
{
int *lastposl;
cache = mmap(cache, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
madvise(cache, size, MADV_NOHUGEPAGE);
// in syscall there is no user libary so I use vmalloc
// cache = vmalloc(size);
for (offset = 0; offset < size; offset += stride) {
lastpos = cache + offset;
*lastpos = offset + stride;
}
*lastpos = 0;
}
访问缓存不是线性的。缓存的偏移量是随机调整的。
在用户级别访问缓存
L3 Miss User: 4133762
Instruction User: 129473219
L3 Miss Kernel: 4418
Instruction Kernel: 4912652
User MPKI: 31.927545
Kernel MPKI: 0.899311
访问内核级别的缓存
L3 Miss User: 41512
Instruction User: 13473121
L3 Miss Kernel: 159178
Instruction Kernel: 39499775828
User MPKI: 3.081098
Kernel MPKI: 0.004030
我两个都独立运行。您可以看到,即使代码相同,但是内核具有大量指令,并且内核中没有缓存未命中。我希望在用户级循环中,系统调用在内核MPKI中应与用户MPKI具有相同或相似的数字。不应该一样吗?