Проверка косвенности указателя на недопустимый доступ к памяти и ошибку сегментации - PullRequest
0 голосов
/ 14 января 2012
struct A { int i; };
...
A *p = (A*) (8); // or A *p = 0;
p->i = 5;    // Undefined Behavior according C/C++ standard

Однако практически большая часть системы будет аварийно завершать работу (ошибка сегментации) для такого кода.

Означает ли это, что все такие Архитектуры / Системы имеют скрытую проверку на косвенность указателя (т. Е. p->), чтобы проверить, обращается ли он к неправильному расположению памяти?

Если да, то это означает, что даже в отлично работающем коде мы платим цену за этот дополнительный чек , верно?

Ответы [ 5 ]

2 голосов
/ 14 января 2012

Да, вы платите цену за этот дополнительный чек.Это не только для косвенного указателя, но и для любого доступа к памяти (кроме, скажем, DMA).Однако стоимость проверки очень мала.

  • Во время выполнения вашего процесса таблица страниц меняется не очень часто.Части таблицы страниц будут кэшироваться в буфере внешнего вида перевода, при этом доступ к страницам с записями в буфере не требует дополнительных штрафов.

  • Если ваш процесс обращается к странице без записи TLB, тоЦП должен сделать дополнительный доступ к памяти, чтобы получить запись таблицы страниц для этой страницы.Затем он будет кэширован.

Вы можете увидеть эффект этого в действии, написав тестовую программу.Дайте вашей тестовой программе большой кусок памяти и начните случайное чтение и запись мест в памяти.Используйте параметр командной строки, чтобы изменить размер.

  • При превышении размера кэша L1 производительность снижается из-за задержки в кэше L2.
  • При превышении размера кэша L2 производительность падает доЗадержка ОЗУ.
  • При превышении размера памяти, адресуемой TLB, производительность падает из-за пропусков TLB.(Это может произойти до или после исчерпания кэш-памяти L2, в зависимости от ряда факторов.)
  • При объеме доступной оперативной памяти производительность будет падать из-за подкачки.
  • Вышеразмер доступного пространства подкачки и оперативной памяти, приложение будет закрыто ОС.

Если ваша операционная система допускает «большие страницы», TLB может действительно охватить очень большое адресное пространство,Возможно, вы можете саботировать ОС, выделяя 4 тыс. Порций из mmap, и в этом случае пропуски TLB могут ощущаться только с несколькими мегабайтами рабочего набора, в зависимости от вашего процессора.

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

2 голосов
/ 14 января 2012

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

Некоторые из потенциальных виртуальных адресов просто не сопоставлены с физической памятью, поэтому преобразование таких вещей, как 8, скорее всего не удастся.

1 голос
/ 14 января 2012

Прежде всего, вам нужно прочитать и понять это: http://en.wikipedia.org/wiki/Virtual_memory#Page_tables

Итак, что обычно происходит, когда процесс пытается разыменовать неверное расположение виртуальной памяти, ОС отлавливает исключение сбоя страницы, вызванное MMU (см. Ссылку выше) для неверного виртуального адреса (0x0, 0x8, что угодно). Затем ОС ищет адрес в своей таблице страниц, не находит его и выдает сигнал SIGSEGV (или аналогичный) процессу, который вызывает сбой процесса.

Разница между действительным и недействительным адресом заключается в том, выделила ли ОС страницу для этого диапазона адресов. Большинство ОС предназначены для того, чтобы никогда не выделять первую страницу (начинающуюся с 0x0), так что разыменования со значением NULL всегда будут аварийно завершаться.

Так что то, что вы называете «дополнительной проверкой», на самом деле является той же проверкой, которая происходит для каждой ошибки страницы, действительного адреса или нет - это просто вопрос успешности поиска таблицы страниц.

1 голос
/ 14 января 2012

Ошибка сегментации - это попытка доступа к памяти, которую ЦП не может физически адресовать.Это происходит, когда оборудование уведомляет операционную систему о нарушении доступа к памяти.Поэтому я думаю, что никакой дополнительной проверки как таковой нет. Если попытка получить доступ к ячейке памяти не удалась, аппаратная часть уведомляет ОС, которая затем отправляет сигнал процессу, вызвавшему исключение.По умолчанию процесс, получающий сигнал, сбрасывает ядро ​​и завершается.

1 голос
/ 14 января 2012

Нет, не правильно.Те же самые проверки абсолютно необходимы при действительном доступе к памяти по двум причинам:

1) В противном случае, как система узнает, к какой физической памяти вы обращались, и была ли страница уже резидентной?

2) В противном случае, как операционная система узнает, какие страницы физической памяти нужно выгружать, если физическая память стала тесной?

Она интегрирована во всю систему виртуальной памяти и является частью того, что заставляет современные компьютеры работать так удивительно хорошо .Это не какая-то отдельная проверка, это часть процесса, которая определяет, к какой странице физической памяти обращается операция.Это часть того, что делает копирование при записи.(Та же самая проверка обнаруживает, когда требуется копия.)

...