При каких обстоятельствах большие страницы могут привести к ускорению? - PullRequest
20 голосов
/ 20 мая 2010

Современные процессоры x86 имеют возможность поддерживать страницы большего размера, чем унаследованные 4 КБ (т.е. 2 МБ или 4 МБ), и есть средства ОС ( Linux , Windows ) для доступа к этому функциональность.

В приведенной выше ссылке Microsoft говорится, что большие страницы "повышают эффективность буфера перевода, что может повысить производительность часто используемой памяти". Что не очень помогает прогнозировать, улучшат ли большие страницы какую-либо ситуацию. Меня интересуют конкретные, предпочтительно количественные примеры того, как перемещение логики программы (или целого приложения) на большие страницы привело к некоторому улучшению производительности. У кого-нибудь есть истории успеха?

Есть один частный случай, который я знаю о себе : использование огромных страниц может значительно сократить время, необходимое для разветвления большого процесса (предположительно, из-за уменьшения числа записей TLB, нуждающихся в копировании на порядок порядка 1000). Меня интересует, могут ли большие страницы быть полезными в менее экзотических сценариях.

Ответы [ 5 ]

16 голосов
/ 13 марта 2012

Наибольшее различие в производительности произойдет, когда вы будете выполнять произвольно расширенный произвольный доступ к большой области памяти, где «большой» означает гораздо больший, чем диапазон, который может отображаться всеми небольшими записями страниц в TLB. (которые обычно имеют несколько уровней в современных процессорах).

Чтобы усложнить задачу, количество записей TLB для страниц размером 4 КБ часто превышает количество записей для страниц размером 2 МБ, но это сильно зависит от процессора. Существует также много различий в количестве записей «больших страниц», доступных в TLB уровня 2.

Например, в системе AMD Opteron Family 10h Revision D («Стамбул») cpuid сообщает:

  • L1 DTLB: 4 КБ страниц: 48 записей; 2 МБ страниц: 48 записей; 1 ГБ страниц: 48 записей
  • L2 TLB: 4 КБ страниц: 512 записей; 2 МБ страниц: 128 записей; 1 ГБ страниц: 16 записей

В системе Intel Xeon 56xx («Westmere») cpuid сообщает:

  • L1 DTLB: 4 КБ страниц: 64 записи; 2MB страниц: 32 записи
  • L2 TLB: страницы 4 КБ: 512 записей; 2 МБ страниц: нет

Оба могут отображать 2 МБ (512 * 4 КБ), используя небольшие страницы, прежде чем потеряет TLB уровня 2, в то время как система Westmere может отображать 64 МБ, используя свои 32 записи TLB 2 МБ, а система AMD может отображать 352 МБ, используя 176 записей TLB 2 МБ в своем TLB L1 и L2. Любая система получит значительное ускорение за счет использования больших страниц для произвольного доступа к диапазонам памяти, которые намного больше, чем 2 МБ и меньше, чем 64 МБ. Система AMD должна продолжать показывать хорошую производительность, используя большие страницы для гораздо большего диапазона памяти.

То, чего вы пытаетесь избежать во всех этих случаях, - это наихудший сценарий (примечание 1) для обхода всех четырех уровней иерархической трансляции адресов x86_64.
Если ни один из механизмов кэширования преобразования адресов (примечание 2) не работает, для этого требуется:

  • 5 поездок в память для загрузки данных, отображаемых на странице 4 КБ,
  • 4 поездки в память для загрузки данных, отображаемых на странице размером 2 МБ, и
  • 3 поездки в память для загрузки данных, отображаемых на странице объемом 1 ГБ.

В каждом случае последняя поездка в память должна получить запрошенные данные, тогда как другие поездки необходимы для получения различных частей информации о переводе страницы. Лучшее описание, которое я видел, приведено в разделе 5.3 «Руководства по программированию для архитектуры AMD64, том 2: Системное программирование» (публикация 24593) http://support.amd.com/us/Embedded_TechDocs/24593.pdf

Примечание 1: Приведенные выше цифры не являются на самом деле худшим случаем. Запуск под виртуальной машиной ухудшает эти показатели. Работа в среде, которая заставляет память, содержащую различные уровни таблиц страниц, переключаться на диск, ухудшает производительность * .

Примечание 2: К сожалению, даже знания этого уровня детализации недостаточно, потому что все современные процессоры имеют дополнительные кэши для верхних уровней иерархии перевода страниц. Насколько я могу судить, они очень плохо документированы в общественных местах.

10 голосов
/ 21 мая 2010

Я попытался придумать какой-нибудь код, который бы максимизировал перегрузку TLB с 4k-страницами, чтобы изучить возможные выгоды от больших страниц. Приведенный ниже материал работает в 2,6 раза быстрее (чем страницы по 4 КБ), если 2-мегабайтные страницы предоставлены malloc libhugetlbfs (Intel i7, 64-битный Debian Lenny); надеюсь, очевидно, что scoped_timer и random0n делают.

  volatile char force_result;

  const size_t mb=512;
  const size_t stride=4096;
  std::vector<char> src(mb<<20,0xff);
  std::vector<size_t> idx;
  for (size_t i=0;i<src.size();i+=stride) idx.push_back(i);
  random0n r0n(/*seed=*/23);
  std::random_shuffle(idx.begin(),idx.end(),r0n);

  {
    scoped_timer t
      ("TLB thrash random",mb/static_cast<float>(stride),"MegaAccess");
    char hash=0;
    for (size_t i=0;i<idx.size();++i) 
      hash=(hash^src[idx[i]]);
    force_result=hash;
  }

Более простая "прямолинейная" версия с hash=hash^src[i] набрала только 16% от больших страниц, но (дикие предположения) необычное аппаратное обеспечение предварительной выборки от Intel может помочь случаю 4K, когда доступ предсказуем предположим, я мог бы отключить предварительную выборку , чтобы выяснить, так ли это).

3 голосов
/ 16 октября 2014

Это становится эзотерическим, но огромные страницы TLB имеют существенное значение для архитектуры Intel Xeon Phi (MIC) при передаче памяти DMA (от хоста к Phi через PCIe). Эта ссылка Intel описывает, как включить огромные страницы .Я обнаружил, что увеличение размера передачи DMA свыше 8 МБ при нормальном размере страницы TLB (4 КБ) начало снижать производительность, с примерно 3 ГБ / с до менее 1 ГБ / с, как только объем передачи достиг 512 МБ.

После включения огромных страниц TLB (2 МБ) скорость передачи данных продолжала увеличиваться до более 5 ГБ / с для передач DMA 512 МБ.

3 голосов
/ 21 мая 2010

Я наблюдал улучшения в некоторых сценариях HPC / Grid - в частности, в физических пакетах с очень и очень большими моделями на машинах с большим и большим количеством оперативной памяти. Кроме того, процесс запуска модели был единственным активным на машине. Я подозреваю, хотя и не измерил, что некоторые функции БД (например, массовый импорт) также выиграют.

Лично я думаю, что, если у вас нет очень хорошо профилированного / понятного профиля доступа к памяти и он обеспечивает большой доступ к памяти, маловероятно, что вы увидите какое-либо существенное улучшение.

2 голосов
/ 21 мая 2010

Я получаю ускорение на ~ 5% на серверах с большим объемом памяти (> = 64 ГБ), на которых выполняются большие процессы. например для процесса Java объемом 16 ГБ это страницы размером 4M x 4 КБ, но только страницы размером 4K x 4 МБ.

...