Насколько косвенность указателя влияет на эффективность? - PullRequest
7 голосов
/ 02 ноября 2011

Разыменование указателя заметно медленнее, чем просто прямой доступ к этому значению?Я предполагаю, что мой вопрос - как быстро работает оператор почтения?

Ответы [ 5 ]

20 голосов
/ 02 ноября 2011

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

Вместо этого на скорость влияют предсказание и кэш.

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

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

Если указатель используется для указателя функции, в игру вступает предиктор ветвления ЦП.В виртуальных таблицах C ++ все значения функций являются постоянными, и предиктор делает это легко.ЦП будет иметь готовый код для запуска и в конвейере, когда выполнение пройдет через косвенный переход.Но, если это непредсказуемый указатель на функцию, влияние на производительность может быть значительным, потому что конвейер должен быть очищен, что тратит 20-40 циклов ЦП на каждый переход.

3 голосов
/ 02 ноября 2011

Зависит от таких вещей, как:

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

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

Если выочень хочу знать, тестировать его на вашем конкретном оборудовании.

2 голосов
/ 02 ноября 2011

Предполагая, что вы имеете дело с реальным указателем (не каким-то умным указателем), операция разыменования вообще не потребляет (данные) памяти.Это (потенциально) требует дополнительной ссылки на память: один для загрузки самого указателя, другой для доступа к данным, на которые указывает указатель.

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

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

2 голосов
/ 02 ноября 2011

Это так. Это стоит дополнительной выборки.
Получая доступ к переменной по значению, переменная непосредственно считывается из ее памяти.
Доступ к этому же через указатель добавляет издержки на выбор адреса переменной из указателя и последующее чтение значения из этой ячейки памяти.

Конечно, при условии, что переменная не помещается в регистр, как это было бы в некоторых сценариях, таких как узкие циклы. Я полагаю, что Вопрос ищет ответ в виде накладных расходов при условии отсутствия таких сценариев.

2 голосов
/ 02 ноября 2011

требуется доступ к памяти больше:

  1. прочитать адрес, сохраненный в переменной указателя
  2. прочитайте значение по адресу, прочитанному

Это не может быть равно 2 простым операциям, поскольку может потребоваться также больше времени из-за доступа к адресу, еще не загруженному в кэш.

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