код rdtsc, показывающий влияние характеристик памяти на производительность, например промах TLB.

Я пытался понять rdtsc() и наткнулся на следующий код с сайта http://www.mcs.anl.gov/~kazutomo/rdtsc.html. Текст, объясняющий код, гласит: «Следующий краткий тестовый код может показать вам некоторые воздействия на производительность из-за характеристик памяти, таких как промах TLB, сбой страницы или подкачка страниц. in/out.». Проблема в том, что я не очень понимаю, как это показывает производительность по характеристикам памяти. Честно говоря, я понятия не имею. Было бы здорово, если бы кто-нибудь мог немного объяснить это.

#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>

#include "rdtsc.h"

#define N (1024*1024*2)

int main(int argc, char* argv[])
{
  unsigned long long a,b;
  unsigned long long min,max;
  char* p;
  int i;

  p = (char*)malloc(N);
  assert( p!=(char*)0 );

  max = 0;
  min = UINT64_MAX;

  for(i=0; i<N; i++ ) {
    a = rdtsc();
    p[i] = 0;
    b = rdtsc() - a;
    if( b > max ) max = b;
    else if( b < min ) min = b;
  }
  printf("min=%llu\n", min);
  printf("max=%llu\n", max);
  return 0;
}

person liv2hak    schedule 21.08.2013    source источник


Ответы (1)


Этот код просто перебирает 2-мегабайтный буфер, записывая 0 в каждый его байт и вычисляя время, необходимое для выполнения каждой записи, обновляя метки нижнего и верхнего уровня (min и max), которые показывают самое короткое и самое длинное время. требуется для выполнения каждой записи.

Предполагая, что эта программа является ЕДИНСТВЕННОЙ программой, работающей на ЦП, и при условии, что во время ее работы не происходит асинхронных событий (аппаратных прерываний или прерываний таймера), эта программа покажет вам как номинальное время для выполнения побайтовой записи в память, так и максимальное количество времени, необходимое для обработки исключения промаха TLB и/или исключения ошибки страницы.

Исключение промаха TLB — это исключение, которое принимает ядро, когда программа пытается получить доступ к памяти, для которой в MMU нет записи TLB. MMU — полицейский на пересечении Core Avenue и Memory Lane, который направляет движение туда, куда оно должно идти. Ладно, это ужасная аналогия. MMU (Memory Management Unit) имеет две основные цели: 1) направлять доступ к виртуальной памяти по соответствующему адресу физической памяти и 2) обеспечивать привилегии только для чтения, чтения-записи, чтения-выполнения, только выполнения и т. д., чтобы случайный доступ указателя к области виртуальной памяти с конфликтующими атрибутами (или к несопоставленной области виртуальной памяти) будет захвачен и вызовет исключение доступа к памяти (например, SIGSEGV в Linux). Запись TLB представляет собой набор аппаратных регистров в MMU, которые сообщают MMU права доступа к странице виртуальной памяти или группе страниц, которые в данный момент загружены в физическую память. Но MMU не имеет бесконечного числа записей TLB; у него недостаточно записей TLB для описания атрибутов всех страниц памяти. Поэтому, если вы попытаетесь получить доступ к юридическому адресу из адресного пространства вашего процесса, у которого нет текущей записи TLB, описывающей страницу, на которой он находится, вы получите исключение промаха TLB. Затем обработчик исключения промаха TLB извлекает данные соответствующей записи TLB из основной памяти и записывает их в запись TLB в MMU; MMU может даже иметь какой-то встроенный механизм для сообщения обработчику исключений промаха TLB, какую запись TLB он должен использовать... вероятно, наименее недавно использованную запись, которая, скорее всего, больше не понадобится в ближайшем будущем. .

Ошибка страницы похожа на исключение промаха TLB, за исключением того, что в этом случае содержимое этой страницы виртуальной памяти даже не находится в физической памяти... оно может вообще не существовать (новосопоставленная страница памяти) или он мог быть ранее выгружен на диск, чтобы освободить место в ограниченной физической памяти для другой страницы виртуальной памяти, которая в какой-то момент потребовалась программе. В то время как исключения промаха TLB обычно довольно быстры (но, тем не менее, влияют на производительность), исключение ошибки страницы может быть ОГРОМНЫМ ударом по производительности, если страница должна быть извлечена с диска (даже с SSD!), поскольку дисковое хранилище обычно на порядок медленнее (или хуже!), чем доступ к памяти. По этой причине, чтобы ЦП был занят работой над чем-то полезным, обработчик исключений сбоя страницы операционной системы часто заставляет текущий процесс переключиться на другой процесс (тот, который находится в состояние «готов»), ожидая получения данных с диска для заполнения запрошенной страницы виртуальной памяти.

Теперь вернемся к этому «тестовому коду» и эффективности его результатов:

Этот тест зависит от того, что среда выполнения ОС + НЕ предварительно выделяет страницы памяти при вызове malloc(N). Я считаю, что это, вероятно, типичное поведение; даже несмотря на то, что среда выполнения выделила столько памяти и знает диапазон адресов, который она выделила, фактические страницы для этой памяти часто не выделяются ОС до тех пор, пока ваша программа не получит доступ (чтение или запись) к адресу на данной странице. Страницы имеют размер 4 КБ на многих платформах, но могут быть и намного больше, например, страницы размером 4 МБ на более новых производных Intel Pentium.

Таким образом, предполагая, что размер страницы вашей платформы составляет 4 КБ (4096 байт), когда ваши программы проходят через выделенное пространство размером 2 МБ, записывая в него 0 по байту за раз, они будут проходить через 1024 из этих 4 КБ страниц. Таким образом, 4193280 таких операций записи должны выполняться «как можно быстрее» (без срабатывания исключения промаха TLB или ошибки страницы). И до 1024 из них вызовут исключения промаха TLB и/или ошибки страницы. Таким образом, «минимальное» время дает максимально быстрое время для выполнения записи, учитывая, что записанный адрес находится в уже загруженной странице виртуальной памяти, а его запись TLB в настоящее время находится в MMU. Максимальное время дает наихудшее возможное время для выполнения записи, предположительно по адресу, который находится на странице, которая еще не отображена в физическую память (и которая вызвала исключение ошибки страницы и, возможно, также исключение промаха TLB).

Есть две проблемы с этим тестом, если мы полагаемся на его результаты, чтобы выявить некоторые характеристики базового оборудования: 1) Сам по себе этот код игнорирует эффект переключения процессов и/или аппаратных прерываний по другим причинам, таким как время - нарезка и сетевые пакеты принимаются и обрабатываются «в фоновом режиме» (что может прервать запущенный процесс). И... 2) 2-мегабайтный тестовый буфер даже не такой большой, как 4-мегабайтный размер страницы MMU новых процессоров Intel. Я не знаю, какие условия определяют, будут ли операционные системы использовать страницы размером 4 КБ или 4 МБ, поэтому это может быть или не быть фактором для вашей системы. Просто имейте в виду, что если ваши min и max имеют один и тот же порядок величин друг с другом, то, скорее всего, вы работаете в системе с 4 МБ страниц, и если ваши min и max отличаются на порядок или более, разница может не может быть полностью связана с исключениями промахов TLB и ошибок страниц. Возможно, именно поэтому автор немного смягчился в своем заявлении о том, что код «может показать вам некоторое влияние на производительность...» (курсив добавлен).

person phonetagger    schedule 22.08.2013