Может ли const-correctness повысить производительность?
Я читал много раз, что принудительное выполнение const-correctness в вашем коде C или С++ является не только хорошей практикой в отношении ремонтопригодности, но также может позволить вашему компилятору выполнять оптимизации. Тем не менее, я прочитал полную противоположность, тоже. что он вообще не влияет на производительность.
Следовательно, есть ли у вас примеры, когда корректность const может помочь вашему компилятору улучшить производительность вашей программы?
Ответы
Ответ 1
Правильность const
не может повысить производительность, потому что const_cast
и mutable
находятся на этом языке и позволяют коду последовательно нарушать правила. Это становится еще хуже в С++ 11, где ваши данные const
могут, например, быть указателем на std::atomic
, что означает, что компилятор должен уважать изменения, сделанные другими потоками.
Тем не менее, для компилятора тривиально посмотреть на код, который он генерирует, и определить, действительно ли он записывается в данную переменную, и соответственно применять оптимизации.
Все сказанное, const
правильность - это хорошая вещь в отношении ремонтопригодности. В противном случае клиенты вашего класса могут сломать внутренние члены этого класса. Например, рассмотрим стандартный std::string::c_str()
- если он не смог вернуть значение const, вы сможете закрутить внутренний буфер строки!
Не используйте const
по соображениям производительности. Используйте его для удобства обслуживания.
Ответ 2
Да, это возможно.
Большинство const
предназначены исключительно для программиста и не помогают оптимизировать компилятор, потому что законно отбрасывать их, и поэтому они не говорят компилятору ничего полезного для оптимизации. Однако некоторые const
не могут быть (юридически) отброшены, и они предоставляют компилятору полезную информацию для оптимизации.
В качестве примера, доступ к глобальной переменной, определенной с типом const
, может быть встроен, а один без типа const
не может быть встроен, поскольку он может меняться во время выполнения.
https://godbolt.org/g/UEX4NB
С++:
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
... но реальные компиляторы не могут.
Ответ 3
по моему опыту, no
Для скалярных переменных компилятор может определять, когда изменяется значение, и выполнять необходимую оптимизацию.
Для указателей массива константная корректность не гарантирует, что значения действительно постоянны при наличии потенциальных проблем с псевдонимом. Следовательно, компилятор не может использовать константный модификатор для выполнения оптимизации
если вы ищете оптимизацию, вы должны рассмотреть __restrict__
или специальные модификаторы/атрибуты функции: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
Ответ 4
Немного устарел, но по-прежнему применяется: http://www.gotw.ca/gotw/081.htm
И еще несколько: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/