Понимание времени отклика обращений к памяти
В рамках академического исследования я выполнил следующий эксперимент:
buff = mmap(NULL, BUFFSIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | HUGEPAGES, -1, 0);
lineAddr = buff;
for (int i = 0; i < BUFFSIZE; i++)
clflush(&(buff[i]));
for (int i = 0; i < LINES; i ++){
srand(rdtscp());
result = memaccesstime(lineAddr);
lineAddr = (void*)((uint64_t)lineAddr + (rand()%20+3)*(8*sizeof(void*)));
resultArr[i] = result;
}
Функция MemAccessTime возвращает время отклика в тактах процессора.
static inline uint32_t memaccesstime(void *v) {
uint32_t rv;
asm volatile (
"mfence\n"
"lfence\n"
"rdtscp\n"
"mov %%eax, %%esi\n"
"mov (%1), %%eax\n"
"rdtscp\n"
"sub %%esi, %%eax\n"
: "=&a" (rv): "r" (v): "ecx", "edx", "esi");
return rv;
}
Итак, шаги:
- Выделил большой диапазон памяти (с помощью mmap ()).
- clflush () вся строка (с циклом for)
- Пробежка по случайным линиям (с шагами от 3 до 23) и измерение времени отклика.
Результаты: Результаты
Пожалуйста, помогите мне лучше понять результаты. Почему после короткого количества образцов время отклика падает?
Примечания: Значение регистра MSR 0x1a4 равно 0xF (но поведение такое же, как и у 0x0). Я выбрал случайные шаги, чтобы избежать предварительного выбора "шага". Есть ли какие-либо другие аппаратные (или программные) средства предварительной выборки, которые могли бы отвечать за эти результаты?