저는 C 또는 C ++ 코드에서 const-correctness를 적용하는 것이 유지 관리 측면에서 좋은 방법 일뿐만 아니라 컴파일러가 최적화를 수행 할 수 있도록 허용 할 수 있다는 것을 여러 번 읽었습니다. 그러나 나는 그 반대도 읽었다. 이것은 성능에 전혀 영향을주지 않는다는 것이다.
따라서 const 정확성이 프로그램의 성능을 향상시키는 데 컴파일러에 도움이 될 수있는 예가 있습니까?
저는 C 또는 C ++ 코드에서 const-correctness를 적용하는 것이 유지 관리 측면에서 좋은 방법 일뿐만 아니라 컴파일러가 최적화를 수행 할 수 있도록 허용 할 수 있다는 것을 여러 번 읽었습니다. 그러나 나는 그 반대도 읽었다. 이것은 성능에 전혀 영향을주지 않는다는 것이다.
따라서 const 정확성이 프로그램의 성능을 향상시키는 데 컴파일러에 도움이 될 수있는 예가 있습니까?
const
은 성능 차이를 만든 예입니다 . stackoverflow.com/questions/1121791/… . 하지만 본질적으로 구현 품질 문제였습니다. const
컴파일러 가 합법적으로 최적화를 수행 할 수 있는지 여부를 결정하지 않았으며 컴파일러 버전이 누락되었을 때이를 수행하지 못하는 경우가 발생했습니다.
답변:
const
때문에 정확성은 성능을 개선 할 수 const_cast
와 mutable
언어, 그리고 일치되게 규칙을 깰 코드를 할 수 있습니다. 이것은 C ++ 11에서 더욱 악화됩니다. const
예를 들어 데이터가에 대한 포인터 일 수 있습니다 std::atomic
. 즉, 컴파일러는 다른 스레드에 의해 변경된 내용을 존중해야합니다.
즉, 컴파일러가 생성하는 코드를보고 주어진 변수에 실제로 쓰는지 확인하고 그에 따라 최적화를 적용하는 것은 간단합니다.
즉, const
정확성은 유지 관리 측면에서 좋은 것입니다. 그렇지 않으면 클래스의 클라이언트가 해당 클래스의 내부 멤버를 손상시킬 수 있습니다. 예를 들어 표준을 고려하십시오 std::string::c_str()
. const 값을 반환 할 수 없다면 문자열의 내부 버퍼를 사용할 수 있습니다!
const
성능상의 이유로 사용하지 마십시오 . 유지 관리를 위해 사용하십시오.
const
는 "당신은 어리석은 일을하고 있습니다"라는 표지판입니다.
예, 그럴 수 있습니다.
대부분 const
의 s는 순전히 프로그래머의 이익을위한 것이며 컴파일러가 최적화하는 데 도움이되지 않습니다. 그러나 일부 const
는 (법적으로) 캐스트 할 수 없으며 최적화에 유용한 정보를 컴파일러에 제공합니다.
예를 들어, const
유형으로 정의 된 전역 변수에 대한 액세스 는 인라인 될 수 있지만 const
유형이없는 변수 는 런타임에 변경 될 수 있으므로 인라인 될 수 없습니다.
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
최적화가 아닙니다.
Steve Jessop은 원래 질문에 대한 그의 의견에서 언급할만한 가치가있는 또 다른 예를 제공합니다. 블록 범위에서 컴파일러는 변수의 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 -값/