Я сделал тест, в котором есть функция чтения строки кэша для измерения MPKI (количество пропущенных кешей инструкций) и syscall
, которая также имеет ту же функцию, но реализована в другом методе (vmalloc).Я ожидал, что MPKI будет одинаковым на обоих уровнях, но пользовательский MPKI слишком высок, чем MPKI ядра.
В настоящее время я использую linux-4.14.84
и измеряю пропуск кэша и количество команд с помощью performance monitoring counter
.В системном вызове я использую 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
Я запускал их оба независимо.Вы можете видеть, что даже если код такой же, но ядро имеет огромное количество команд и в ядре нет ошибок кэша.Я ожидаю, что syscall должен иметь такой же или похожий номер в Kernel MPKI с пользовательским MPKI в цикле на уровне пользователя.Разве это не должно быть одинаковым?