Может ли добавление const к указателю помочь оптимизации? - PullRequest
15 голосов
/ 31 января 2012

У меня есть указатель int* p, и я выполняю некоторые операции в цикле. Я не изменяю память, просто читаю. Если я добавлю const к указателю (в обоих случаях, const int* p и int* const p), может ли это помочь компилятору оптимизировать код?

Я знаю другие достоинства const, такие как безопасность или самодокументирование, я спрашиваю об этом конкретном случае. Перефразируя вопрос: может ли const дать компилятору какую-либо полезную (для оптимизации) информацию, когда-либо?

Ответы [ 6 ]

6 голосов
/ 31 января 2012

Хотя это, очевидно, характерно для реализации, трудно понять, как изменение указателя с int* на int const* могло бы когда-либо предоставить любую дополнительную информацию, которую компилятор иначе не знал бы.

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

Поэтому это, вероятно, не поможет компилятору оптимизировать код.

3 голосов
/ 31 января 2012

Нет. Подобное использование const не даст компилятору никакой информации, которую можно использовать для оптимизации.

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

Херб Саттер раскрывает эту глубину в одном из своих Гуру недели столбцов.

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

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

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

1 голос
/ 01 февраля 2012

Вы не говорите, какой компилятор вы используете. Но если вы читаете и записываете в память, вы можете воспользоваться «ограничить» или подобным. Компилятор не знает, используют ли ваши указатели псевдонимы для одной и той же памяти, поэтому любое хранилище часто заставляет снова загружать другие значения. «restrict» сообщает компилятору, что псевдоним указателя не происходит, и может продолжать использовать значения, загруженные перед последующей записью. Другой способ избежать проблемы псевдонимов - загрузить ваши значения в локальные переменные, после чего компилятору не придется перезагружаться после записи.

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

Использование const, как все говорили, вряд ли поможет компилятору оптимизировать ваш цикл.

Это может, однако, помочь оптимизировать код вне цикла, или на месте вызова метода, удовлетворяющего const, или функции, принимающей аргументы const.

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

Единственный способ доказать это - профилировать и / или проверять сборку, но это то, что вы, вероятно, должны искать.

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

Я думаю, что компилятор не может многое сделать в вашем сценарии.Тот факт, что ваш указатель объявлен как const int * const p, не гарантирует, что память не может быть изменена извне, например, другим потоком.Поэтому компилятор должен генерировать код, который считывает значение памяти на каждой итерации цикла.

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

const int * p = ...
...
int val = *p;
/* use the value in a loop */
for (i = 0; i < BAZILLION; i++)
{
    use_value(val);
}

Не только вы помогаете потенциальным читателям вашего кода увидеть, чтоval не изменяется в цикле, но вы также даете компилятору возможность оптимизировать (например, загрузить val в регистр).

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