programing

C에서 반환 값 최적화 및 복사 제거

firstcheck 2021. 1. 15. 08:18
반응형

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

반응형