Измерение эффектов TLB на Cortex-A9

Прочитав следующий документ https://people.freebsd.org/~lstewart/articles/cpumemory.pdf («Что должен знать каждый программист о памяти») Я хотел попробовать один из авторских тестов, то есть измерить влияние TLB на окончательное время выполнения.

Я работаю над Samsung Galaxy S3, который включает Cortex-A9.

По документации:

Я написал небольшую программу, которая выделяет массив структур с N записями. Размер каждой записи == 32 байта, поэтому она умещается в строке кэша. Я выполняю несколько обращений для чтения и измеряю время выполнения.

typedef struct {
     int elmt; // sizeof(int) == 4 bytes
     char padding[28]; // 4 + 28 = 32B == cache line size
}entry;


volatile entry ** entries = NULL;

//Allocate memory and init to 0
entries = calloc(NB_ENTRIES, sizeof(entry *));
if(entries == NULL) perror("calloc failed"); exit(1);

for(i = 0; i < NB_ENTRIES; i++)
{
      entries[i] = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
      if(entries[i] == MAP_FAILED) perror("mmap failed"); exit(1);
}

entries[LAST_ELEMENT]->elmt = -1

//Randomly access and init with random values
n = -1;
i = 0;
while(++n < NB_ENTRIES -1)
{
      //init with random value
      entries[i]->elmt = rand() % NB_ENTRIES;

      //loop till we reach the last element
      while(entries[entries[i]->elmt]->elmt != -1)
      {
            entries[i]->elmt++;
            if(entries[i]->elmt == NB_ENTRIES)
                     entries[i]->elmt = 0;
      }

       i = entries[i]->elmt;
}


gettimeofday(&tStart, NULL);
for(i = 0; i < NB_LOOPS; i++)
{
     j = 0;
     while(j != -1)
     {
          j = entries[j]->elmt
     }
}
gettimeofday(&tEnd, NULL);

time = (tEnd.tv_sec - tStart.tv_sec);
time *= 1000000;
time += tEnd.tv_usec - tStart.tv_usec;
time *= 100000
time /= (NB_ENTRIES * NBLOOPS);

fprintf(stdout, "%d %3lld.%02lld\n", NB_ENTRIES, time / 100, time % 100);

У меня есть внешний цикл, который изменяет NB_ENTRIES от 4 до 1024.

Как видно на рисунке ниже, пока NB_ENTRIES == 256 записей, время выполнения больше.

Когда NB_ENTRIES == 404 появляется сообщение «Недостаточно памяти» (почему? Превышены микро TLB? Превышены основные TLB? Превышены таблицы страниц? Превышена виртуальная память для процесса?)

Может кто-нибудь объяснить мне, пожалуйста, что на самом деле происходит от 4 до 256 записей, а затем от 257 до 404 записей?

Влияние TLB на время выполнения

ИЗМЕНИТЬ 1

Как было предложено, я выполнил мембенч (src code) и ниже результаты:

результаты членства

ИЗМЕНИТЬ 2

В следующей статье (стр. 3) они были выполнены (я полагаю ) тот же тест. Но разные шаги хорошо видны по их сюжетам, что не в моем случае.

введите описание изображения здесь

Прямо сейчас, по их результатам и объяснениям, я могу выделить лишь несколько вещей.

  • графики подтверждают, что размер строки кэша L1 составляет 32 байта, потому что, как они сказали

«как только размер массива превышает размер кэша данных (32 КБ), чтения начинают генерировать промахи [...] точка перегиба возникает, когда каждое чтение генерирует промахи».

В моем случае самая первая точка перегиба появляется, когда шаг == 32 байта. - График показывает, что у нас кеш второго уровня (L2). Я думаю, что это изображено желтой линией (1 МБ == размер L2) - поэтому два последних графика над последним, вероятно, отражают задержку при доступе к основной памяти (+ TLB?).

Однако из этого теста я не могу идентифицировать:

  • ассоциативность кеша. Обычно D-Cache и I-Cache являются четырехсторонними ассоциативными (Cortex-A9 TRM).
  • Эффекты TLB. Как они сказали,

в большинстве систем вторичное увеличение задержки указывает на TLB, который кэширует ограниченное количество виртуальных преобразований в физические. [..] Отсутствие увеличения задержки, связанного с TLB, указывает на то, что [...] "

вероятно, были использованы / реализованы большие размеры страниц.

ИЗМЕНИТЬ 3

Эта ссылка объясняет эффекты TLB от другого графа-элемента. Фактически можно получить те же эффекты на моем графике.

В страничной системе 4 КБ, по мере того, как вы набираете успех, пока они все еще <4 КБ, вы будете все меньше и меньше пользоваться каждой страницей [...] вам придется обращаться к TLB 2-го уровня при каждом доступе [ ...]

Cortex-A9 поддерживает страницы размером 4 КБ режим. Действительно, как видно на моем графике до шагов == 4K, задержки увеличиваются, а затем, когда они достигают 4K

вы внезапно снова начинаете получать выгоду, поскольку фактически пропускаете целые страницы.


person D4l3k    schedule 29.05.2015    source источник
comment
Вы забыли отменить отображение записей? Это определенно объяснило бы нехватку памяти.   -  person ElderBug    schedule 29.05.2015
comment
гул на самом деле да, но если я не отменю сопоставление записей, какая память у меня закончится? выделил виртуальное пространство для моего процесса?   -  person D4l3k    schedule 29.05.2015
comment
да. У ЦП не должно быть памяти, ее использование прозрачно. Таким образом, у вас может закончиться только виртуальная память, которая часто связана с физической оперативной памятью и пространством подкачки. Кстати, вы должны включить код для InitWithRandomValues, поскольку он, кажется, определяет, как вы получаете доступ к памяти.   -  person ElderBug    schedule 29.05.2015
comment
не проверял ваш код, но в лучшем случае вы измеряете (видите эффект) размер кеша / размер строки кеша. TLB - это еще одна проблема. Не знаю, как вы могли бы измерить эффект, который он оказывает, кроме идентичного оборудования, но без TLB.   -  person bolov    schedule 29.05.2015
comment
@bolov очищает TLB перед каждым доступом, вероятно, но я не вижу этого и в опубликованном коде.   -  person Jonas Schäfer    schedule 29.05.2015
comment
L1 и L2 доминируют на ARM. TLB (и микро-TLB) - это отдельные структуры; связанные с отображениями таблиц страниц MMU. Для секций / суперсекций нагрузка небольшая. Это зависит от сопоставлений ОС; они объединяют записи вместе или все это страница размером 4К? В любом случае TLB на ARM не имеет значения по сравнению с L1 / L2 для большинства рабочих нагрузок.   -  person artless noise    schedule 29.05.2015
comment
Он очищает TLB, используя mmap() для распределения новых таблиц MMU. Есть cachebench, membersch и т. Д., Которые дадут более точные измерения. Этот код не является хорошим набором тестов.   -  person artless noise    schedule 29.05.2015
comment
О, я не знал, что mmap () подразумевает, что TLB очищается. Действительно, вы правы, этот код не является хорошим набором тестов, я просто пытался делать что-то с нуля, чтобы я мог (может быть) лучше понять, вместо того, чтобы напрямую использовать существующие инструменты.   -  person D4l3k    schedule 29.05.2015
comment
Также может быть информативным просто использовать perf для подсчета промахов TLB по сравнению с промахами в кэше и т. Д. Для различных битов кода.   -  person Notlikethat    schedule 29.05.2015
comment
Нет ничего плохого в том, чтобы пытаться изобретать вещи заново. Однако вы можете сэкономить время, просмотрев существующие решения. Просто запустите members и посмотрите, дает ли ваш тест аналогичные или разные результаты. Кроме того, вы можете пометить тегом linux или соответствующим тегом ОС, чтобы мы могли вносить предложения, такие как perf, если он существует для вашей ОС.   -  person artless noise    schedule 31.05.2015
comment
Вы имеете в виду это под членством? bebop.cs.berkeley.edu/notes/matmul2002/membench/membench. c cs.berkeley.edu/~demmel / cs267_Spr99 / Assignments / members /   -  person D4l3k    schedule 01.06.2015
comment
Вы могли опубликовать свои результаты / правки членства в качестве ответа. Я согласен с тем, что «выпуклость» на графике вызвана эффектами TLB. Я думаю, что статья Дреппера для x86 с кешем PIPT. Более старый ARM - это VIVT, и нет необходимости в TLB при попадании в кеш. (Я думаю, Cortex-A15 - это PIPT, а возможно, и все ARMv8). Кто-то еще также был обеспокоен TLB на ARM.   -  person artless noise    schedule 11.10.2015
comment
Этот код также никогда не освобождает записи перед выполнением следующего внешнего цикла.   -  person stark    schedule 28.02.2016
comment
Вопрос: Графики из статьи взяты из Cray и Dec Alpha. Ожидаете ли вы увидеть какую-то корреляцию между этими результатами и процессором вашего мобильного телефона?   -  person Bing Bang    schedule 16.06.2016
comment
Неа. Я просто хотел визуализировать и понять поведение процессора на мобильном устройстве без использования автоматизированного инструмента, такого как, например: perf perf.wiki.kernel.org/index.php/Main_Page. От ЦП (eecs.berkeley.edu/Pubs/TechRpts /1992/CSD-92-684.pdf) на графические процессоры (arxiv.org/pdf/ 1509.02308.pdf) существуют различные методы, чтобы выделить эффект иерархии памяти.   -  person D4l3k    schedule 16.06.2016
comment
Эта строка вашего кода выглядит очень странно: if(entries[i] == MAP_FAILED) perror("mmap failed"); exit(1);. Без фигурных скобок вокруг блока кода это означает, что вы всегда выходите.   -  person Sjlver    schedule 21.06.2016
comment
The main TLB is located in L2. Это распространенное заблуждение. L2TLB - это второй уровень для L1TLB, точно так же, как кэш L2 является вторым уровнем для кешей L1D и L1I. L2TLB не использует записи и не заботится о содержимом обычного кэша L2. Связанное описание звучит так, как Intel реализует многоуровневые TLB на мощных процессорах x86, таких как Haswell, с небольшими / быстрыми TLB L1I и L1D и большим общим пулом, который не является полностью ассоциативным. Схема в статье Кантера должна быть полезной.   -  person Peter Cordes    schedule 23.08.2016
comment
Использует ли Linux прозрачные огромные страницы в системе, на которой вы тестировали ? Документ, который вы связали, показывает, что TLB поддерживают огромные страницы размером 1 МБ и 16 МБ (которые ARM вызывает (супер) разделы), поэтому весь блок может быть отображен несколькими записями TLB (что приводит к отсутствию пропусков TLB после начального периода прогрева мягкого страница пропускает, поскольку ядро ​​связывает каждую страницу, а затем замечает, что может использовать огромную страницу.). Ищите запись AnonHugePages: в /proc/meminfo, отличную от нуля.   -  person Peter Cordes    schedule 23.08.2016
comment
Стандарт C не требует, чтобы calloc предоставляла выровненную память, и я не вижу, где нужно позаботиться о выравнивании по 32-байтовым границам. Вы уверены, что выравниваете правильно? stackoverflow.com/ нет выровненного calloc questions / 23092621 /   -  person stark    schedule 19.11.2016


Ответы (1)


tl; dr -> Предоставьте правильный MVCE.

Этот ответ должен быть комментарием, но он слишком велик для публикации в качестве комментария, поэтому вместо этого отправьте его в качестве ответа:

  1. Пришлось исправить кучу синтаксических ошибок (отсутствие точек с запятой) и объявить неопределенные переменные.

  2. После исправления всех этих проблем код НИЧЕГО не сделал (программа завершилась даже до выполнения первого mmap. Я даю совет постоянно использовать фигурные скобки, вот ваша первая и ваша вторая ошибка, вызванная НЕ выполнением этого:

.

// after calloc:
if(entries == NULL) perror("calloc failed"); exit(1);
// after mmap
if(entries[i] == MAP_FAILED) perror("mmap failed"); exit(1);

обе строки просто завершают вашу программу независимо от условия.

  1. Здесь у вас есть бесконечный цикл (переформатирован, добавлены фигурные скобки, но без других изменений):

.

//Randomly access and init with random values
n = -1;
i = 0;
while (++n < NB_ENTRIES -1) {
    //init with random value
    entries[i]->elmt = rand() % NB_ENTRIES;

    //loop till we reach the last element
    while (entries[entries[i]->elmt]->elmt != -1) {
        entries[i]->elmt++;
        if (entries[i]->elmt == NB_ENTRIES) {
            entries[i]->elmt = 0;
        }
    }

    i = entries[i]->elmt;
}

Первая итерация начинается с установки для entries[0]->elmt некоторого случайного значения, затем внутренний цикл увеличивается до тех пор, пока не достигнет LAST_ELEMENT. Затем i устанавливается на это значение (т.е. LAST_ELEMENT), и второй цикл перезаписывает конечный маркер -1 на какое-то другое случайное значение. Затем он постоянно увеличивает значение мода NB_ENTRIES во внутреннем цикле, пока вы не нажмете CTRL + C.

Заключение

Если вам нужна помощь, опубликуйте минимальный, полный и проверяемый пример, а не что-то еще.

person Bodo Thiesen    schedule 29.11.2016