Почему изменение инструкции вызывает огромный i-cache и i-TLB на x86? - PullRequest
0 голосов
/ 16 сентября 2018

Следующий фрагмент кода создает функцию (забаву) только с одной инструкцией RET. Цикл повторно вызывает функцию и перезаписывает содержимое инструкции RET после возврата.

#include <sys/mman.h>
#include<stdlib.h>
#include<unistd.h>
#include <string.h>

typedef void (*foo)();
#define RET (0xC3)

int main(){
     // Allocate an executable page
    char * ins = (char *) mmap(0, 4096, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE| MAP_ANONYMOUS, 0, 0);
    // Just write a RET instruction
    *ins = RET;
    // make fun point to the function with just RET instruction
    foo fun = (foo)(ins);
    // Repeat 0xfffffff times
    for(long i = 0; i < 0xfffffff; i++){
        fun();
        *ins = RET;
    }
    return 0;
}

Linux perf на X86 Broadwell имеет следующую статистику icache и iTLB:

perf stat -e L1-icache-load-misses -e iTLB-load-misses ./a.out

Статистика счетчика производительности для './a.out':

   805,516,067      L1-icache-load-misses                                       
         4,857      iTLB-load-misses                                            

  32.052301220 seconds time elapsed

Теперь посмотрите на тот же код, не переписывая инструкцию RET.

#include <sys/mman.h>
#include<stdlib.h>
#include<unistd.h>
#include <string.h>

typedef void (*foo)();
#define RET (0xC3)

int main(){
    // Allocate an executable page
    char * ins = (char *) mmap(0, 4096, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE| MAP_ANONYMOUS, 0, 0);
    // Just write a RET instruction
    *ins = RET;
    // make fun point to the function with just RET instruction
    foo fun = (foo)(ins);
    // Repeat 0xfffffff times
    for(long i = 0; i < 0xfffffff; i++){
        fun();
        // Commented *ins = RET;
    }
    return 0;
}

А вот статистика перфорации на той же машине.

perf stat -e L1-icache-load-misses -e iTLB-load-misses ./a.out

Статистика счетчика производительности для './a.out':

        11,738      L1-icache-load-misses                                       
           425      iTLB-load-misses                                            

   0.773433500 seconds time elapsed

Обратите внимание, что перезапись инструкции приводит к увеличению L1-icache-load-misses с 11 738 до 80 5 51 0 067 - многократный рост. Также обратите внимание, что количество пропущенных загрузок iTLB увеличилось с 425 до 4857 - довольно много, но меньше по сравнению с пропусками L1-icache-load-misses. Продолжительность увеличивается с 0,773433500 секунд до 32,052301220 секунд - рост в 41 раз!

Неясно, почему ЦП должен вызывать промахи в i-cache, если занимаемая площадь слишком мала. Единственная разница в двух примерах заключается в том, что инструкция модифицирована. Конечно, L1 iCache и dCache разделены. Разве нет способа установить код в iCache, чтобы избежать ошибок в i-cache кеша?

Кроме того, почему 10-кратный рост числа пропусков iTLB?

1 Ответ

0 голосов
/ 16 сентября 2018

Конечно, L1 iCache и dCache разделены. Разве нет способа установить код в iCache, чтобы избежать ошибок в i-cache кеша?

номер

Если вы хотите изменить код - единственный путь, по которому это можно сделать, это следующий:

  1. Дата хранения Двигатель исполнения
  2. Хранение буфера и пересылка
  3. Кэш данных L1
  4. Унифицированный кэш L2
  5. L1 Кэш инструкций

Обратите внимание, что вы также пропускаете кэш-память µOP.

Это иллюстрируется этой диаграммой 1 , которая, на мой взгляд, является достаточно точной.

Я подозреваю, что пропуски iTLB могут быть вызваны регулярными сбросами TLB. В случае отсутствия изменений вы не будете затронуты пропусками iTLB, потому что ваши инструкции на самом деле приходят из кеша µOP.

Если нет, я не совсем уверен. Я бы подумал, что кэш инструкций L1 виртуально адресован, поэтому нет необходимости обращаться к TLB, если есть попадание.

1: к сожалению, авторские права на изображение очень ограничены, поэтому я воздерживаюсь от выделения пути / вставки изображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...