C에서 반환 값 최적화 및 복사 제거
어떤 사람들은 C의 값으로 구조체를 전달하고 반환 하는 것이 가능 하다는 것을 알지 못합니다 . 내 질문은 컴파일러가 C에서 구조체를 반환 할 때 불필요한 복사본을 만드는 것에 관한 것입니다. GCC와 같은 C 컴파일러는 반환 값 최적화 (RVO) 최적화를 사용합니까 아니면 C ++ 전용 개념입니까? RVO 및 복사 제거에 대해 읽은 모든 것은 C ++에 관한 것입니다.
예를 들어 보겠습니다. 저는 현재 C에서 double-double 데이터 유형 을 구현하고 있습니다 (또는 단위 테스트가 쉽기 때문에 시작하려면 float-float). 다음 코드를 고려하십시오.
typedef struct {
float hi;
float lo;
} doublefloat;
doublefloat quick_two_sum(float a, float b) {
float s = a + b;
float e = b - (s - a);
return (doublefloat){s, e};
}
컴파일러는 doublefloat
내가 반환 한 값 의 임시 복사본을 만들거나 임시 복사본을 제거 할 수 있습니까?
C에서 명명 된 반환 값 최적화 (NRVO)는 어떻습니까? 다른 기능이 있습니다
doublefloat df64_add(doublefloat a, doublefloat b) {
doublefloat s, t;
s = two_sum(a.hi, b.hi);
t = two_sum(a.lo, b.lo);
s.lo += t.hi;
s = quick_two_sum(s.hi, s.lo);
s.lo += t.lo;
s = quick_two_sum(s.hi, s.lo);
return s;
}
이 경우 명명 된 구조체를 반환합니다. 이 경우 임시 사본을 제거 할 수 있습니까?
이것은 C에 대한 일반적인 질문이며 여기에서 사용한 코드 예제는 단지 예제 일뿐입니다 (이를 최적화 할 때 어쨌든 내장 함수와 함께 SIMD를 사용할 것입니다). 컴파일러가하는 일을보기 위해 어셈블리 출력을 볼 수 있다는 것을 알고 있지만 그럼에도 불구하고 이것은 흥미로운 질문이라고 생각합니다.
RVO / NRVO는 C의 "as-if"규칙에 따라 명확하게 허용됩니다.
C ++에서는 생성자, 소멸자 및 / 또는 할당 연산자를 오버로드하여 이러한 부작용을 제공하기 때문에 (예 : 이러한 작업 중 하나가 발생할 때 인쇄) 관찰 가능한 부작용을 얻을 수 있지만 C에서는 그렇지 않습니다. 이러한 연산자를 오버로드 할 수있는 능력이 있으며 내장 된 연산자에는 관찰 가능한 부작용이 없습니다.
오버로딩하지 않으면 복사 제거로 인한 부작용이 관찰되지 않으므로 컴파일러가이를 수행하는 것을 막을 수 없습니다.
C ++에서 많이 다루어지는 이유는 C ++에서 RVO에 부작용이 있기 때문입니다 (즉, 임시 객체의 소멸 자나 복사 생성자 또는 결과 객체의 할당 연산자를 호출하지 않음).
C에서는 가능한 부작용이없고 잠재적 인 성능 향상 만 있습니다. 일부 컴파일러에서 이러한 최적화를 수행 할 수없는 이유가 없습니다. 적어도 표준에서 그것을 금지하는 것은 없습니다.
어쨌든 최적화는 컴파일러와 최적화 수준에 따라 다르기 때문에 사용 된 컴파일러가 잘 정의되어 있고 변경 될 것으로 예상되지 않는 한 (여전히 자주 발생하는 경우) 중요한 코드 경로에 내기하지 않을 것입니다.
참조 URL : https://stackoverflow.com/questions/30034171/return-value-optimization-and-copy-elision-in-c
'programing' 카테고리의 다른 글
C ++ 크로스 플랫폼 라이브러리 및 바인딩을위한 최상의 폴더 구조 (0) | 2021.01.16 |
---|---|
Tomcat에서 배포 해제 메모리 누수를 피할 수있는 방법이 있습니까? (0) | 2021.01.16 |
WinForms C #의 우아한 로그 창 (0) | 2021.01.15 |
자바 최종 수정 자 (0) | 2021.01.15 |
git : 권한 문제와 관련된 푸시 할 수 없음 (패커 풀기 오류) (0) | 2021.01.15 |