문제

나는 가능할 때마다 내 루틴이 (N)RVO를 활용하고 있는지 확인하고 싶습니다.결과 디스어셈블리를 분석하는 것 외에 루틴이 (N)RVO로 컴파일되고 있는지 확인하거나 확인할 수 있는 방법이 있습니까?현재 저는 주로 MSVC와 GCC에 관심이 있습니다.

도움이 되었습니까?

해결책

아니 정말.

그러나 코드를 작성할 때 지침을 따를 수 있습니다.


명명되지 않은 반환 값 최적화

이는 디버그 모드에서도 임시 항목을 반환할 때마다 거의 트리거됩니다.

return MyObject(....);

명명된 반환 값 최적화

이는 함수가 항상 동일한 임시 개체를 반환할 때마다 거의 트리거됩니다.

MyObject func() {
  MyObject result;
  if (...) { return result; }

  result.push(0);
  return result;
}

이를 혼합할 수 있지만 이 경우 컴파일러가 RVO를 적용하는 것이 거의 불가능해집니다.

MyObject func() {
  MyObject result;
  if (...) { return MyObject(...); }

  return result;
}

여기서 한 수익은 RVO의 혜택을 받고 다른 수익은 그렇지 않을 가능성이 높습니다.추측에 따라 생성하면 막힐 수 있으므로 첫 번째 최적화에 베팅하겠습니다. result 반환 슬롯에 갑자기 가져 가야합니다 if 나뭇가지.단순히 명령문의 순서를 변경하면 작동합니다.

MyObject func() {
  if (...) { return MyObject(...); }

  MyObject result;

  return result;
}

따라서 NRVO의 경험 법칙은 다음과 같습니다. return 선언 사이의 진술 result 그리고 return result; 이외의 것을 반환하는 문 result 그 자체.


이것을 따르면, 당신에게 유리한 확률이 쌓이게 됩니다.그리고 그것은 단지 코드 검토의 문제일 뿐입니다.

또한 변수가 실제로 필요하다는 것을 알기 전에는 변수를 선언하지 않으므로 코드를 더 쉽게 읽을 수 있습니다.

다른 팁

디버그 메소드를 소멸자에 추가 할 수 있습니다.

struct A
{
   ~A() { cout << "destructor called"; }
};

A foo()
{
   A a;
   return a;
}
.

소멸자가 호출되면 RVO가 적용되지 않을 것입니다.

내가 생각할 수있는 가능한 방법은 다음과 같습니다.

  1. 클래스를 통해 생성 된 인스턴스의 수를 추적하는 클래스 내에서 참조 카운트 메커니즘을 구현하는 것은 shared_ptr와 매우 흡사합니다.이 방법으로 클래스의 추가 복사본을 탐지하여 생성되고 제거됩니다.사본 엘리망이 일어나지 않아.

  2. 복사 엘리전이 발생하지 않는 경우 복사 생성자와 소멸자에 디버그 트레이스를 넣을 수 있습니다. 연속적인 복사본 생성자 및 소멸자 디버그 트레이스를 많이 볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top