Может ли const-корректность повысить производительность?


Я много раз читал, что применение const-корректности в вашем коде C или C++ является не только хорошей практикой в отношении ремонтопригодности, но также может позволить вашему компилятору выполнять оптимизацию. Однако я тоже прочитал полную противоположность-что это вообще не влияет на производительность.

поэтому, есть ли у вас примеры, где корректность const может помочь вашему компилятору улучшить производительность вашей программы?

4 64

4 ответа:

const корректность не может улучшить производительность, потому что const_cast и mutable находятся в языке и позволяют коду соответственно нарушать правила. Это становится еще хуже в C++11, где const данные могут, например, быть указателем на std::atomic, что означает, что компилятор должен учитывать изменения, внесенные другими потоками.

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

этим все сказано, const правильность-это хороший дело в отношении ремонтопригодности. В противном случае клиенты вашего класса могут нарушить внутренние члены этого класса. Например, рассмотрим стандарт std::string::c_str() -- если бы он не мог вернуть значение const, вы могли бы закрутить с внутренним буфером строки!

не используйте const по соображениям производительности. Используйте его по причинам ремонтопригодности.

Да, это может.

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

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

https://godbolt.org/g/UEX4NB

C++:

int foo1 = 1;
const int foo2 = 2;

int get_foo1() {
    return foo1;
}

int get_foo2() {
    return foo2;
}

asm:

foo1:
        .long   1
foo2:
        .long   2
get_foo1():
        push    rbp
        mov     rbp, rsp
        mov     eax, DWORD PTR foo1[rip] ; foo1 must be accessed by address
        pop     rbp
        ret
get_foo2():
        push    rbp
        mov     rbp, rsp
        mov     eax, 2 ; foo2 has been replaced with an immediate 2
        pop     rbp
        ret

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


Стив Джессоп дает еще один пример в своем комментарии к исходному вопросу, который поднимает что-то достойное упоминания. В области блока компилятор может вывести, будет ли переменная мутирована и оптимизирована соответствующим образом, независимо от const, потому что компилятор может увидеть любой переменной. Напротив, в приведенном выше примере невозможно предсказать, если foo1 будет изменен, так как он может быть изменен в других единицах перевода. Я полагаю, что гипотетический разумный ультра-компилятор может проанализировать всю программу и определить, если это действительно для встроенного доступа к foo1... но настоящие компиляторы не могут.

по моему опыту, нет

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

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

Если вы ищете оптимизацию, вы должны рассмотреть __restrict__ или специальные функции модификаторы / атрибуты:http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html

немного старый, но все еще применяется: http://www.gotw.ca/gotw/081.htm И еще: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/