2011-09-22 2 views
7

C++ 표준은 예상 기능을 실제로 방해 할 수있는 지점까지 최적화를 허용한다는 것을 읽었습니다. 이 말을 할 때, 나는 반환 값 최적화에 대해 말하고있다. 여기서 복사 생성자에 실제로 어떤 논리가있을 수 있지만 컴파일러는 호출을 최적화한다.C++ 최적화에 관한 질문

이 사실을 모르는 사람은이 문제로 인해 버그를 수정하는 데 꽤 시간을 할애 할 수 있으므로 다소 나쁘다.

내가 알고 싶은 것은 컴파일러의 최적화가 기능을 변경할 수있는 다른 상황이 있는지 여부입니다. 같은

예를 들어

, 뭔가 :

int x = 1; 
x = 1; 
x = 1; 
x = 1; 

가 최적화 될 수있는 하나의 X = 1;

가정하자 나는 한 :

class A; 

A a = b; 
a = b; 
a = b; 

이 가능성도 최적화 할 수 있을까요? 아마 가장 좋은 예,하지만 난는 컴파일러가 부작용이 눈에 띄게을 변경 곳에 지점으로 최적화 할 수있는 유일한 경우입니다 ... 당신이 무슨 뜻인지 아시죠

+4

나는 근접 투표에 동의하지 않는다. 이것은 진정하고 답할만한 질문입니다. –

+4

copy ctor를 없애면 코드의 버그가 발생하고 처음에는 잘못 ctor를 고안했습니다. 코드가 얼마나 많은 객체가 있는지 또는 객체가 복사/할당되는 빈도에 의존해서는 안됩니다. – PlasmaHH

+1

copy ctor의 논리는 객체를 복사하기위한 논리 여야합니다. 복사되지 않으면 ctor 논리를 복사해야하는 이유는 무엇입니까? –

답변

12

Eliding 복사 작업 희망. 호출되는 복사 생성자에 의존하지 말고 컴파일러는 이러한 호출을 최적화 할 수 있습니다.

그 외 모든 경우 "as-if"규칙이 적용됩니다. 컴파일러는 컴파일러가 전혀 최적화하지 않은 것처럼 보이는 부작용이있는 한 원하는만큼 최적화 할 수 있습니다.

("눈에 보이는 부작용"을 포함, 예를 들어, 콘솔이나 파일 시스템에 기록,하지만 물건은 CPU 팬 속도 런타임합니다.)

+0

+1 : "부작용이 눈에 띄게 바뀝니다." 눈에 보이는 부작용이 실제로 무엇인지에 대한 가치가있을 수 있습니다. –

+1

이 값은 r 값이 도입되기 전에 있었던 것입니다. 최적화가 허용되었습니다. 이제는 r 값이 존재하기 때문에 이러한 최적화는 관련이 없습니다 (복사 추출은 이동 생성자를 호출하는 것보다 빠르지 만 같은 여백을 사용하지 않는 것보다 빠름). 이전 버전과의 호환성이 아닌 동작이 보존되었지만 여전히 이익을 제공하고 사람들은 복사 생성자를 트릭을 위해 사용하지 않는 것을 배웠습니다. –

+0

@Rob : 그게 당신의 취향에 딱 맞을까요?) – sbi

1

class A이 구현되는 방법에 따라 달라집니다, 컴파일러 여부 구현을 볼 수 있고 그것이 충분히 영리한 지 여부를 알 수 있습니다. 예를 들어, class Aoperator=()에 몇 가지 부작용이있는 경우 최적화가 프로그램 동작을 변경하고 가능하지 않을 수 있습니다.

3

최적화되어있을 수도 있습니다. 그렇습니다. 그러나 당신은 여전히 ​​예를 들어, 가정 해 코드의 프로세스에 대한 일부 제어 할 수 있습니다 :

 
    int x = 1; 
    x = 1; 
    x = 1; 
    x = 1; 
    volatile int y = 1; 
010B1004 xor   eax,eax 
010B1006 inc   eax 
010B1007 mov   dword ptr [y],eax 
    y = 1; 
010B100A mov   dword ptr [y],eax 
    y = 1; 
010B100D mov   dword ptr [y],eax 
    y = 1; 
010B1010 mov   dword ptr [y],eax 

즉 :

int x = 1; 
x = 1; 
x = 1; 
x = 1; 
volatile int y = 1; 
y = 1; 
y = 1; 
y = 1; 

도 X 없으며, y는이 조각 이하로 사용하는 것을 제공, VS 2010 코드 생성 최적화는 모든 행을 "x"로 제거하고 모든 4 개의 행을 "y"로 남겨 둡니다. 이것은 휘발성가 작동하는 방식이지만, 요점은 당신이 여전히 컴파일러를 제어 할 수 있다는 것입니다.

클래스 또는 기본 유형 (모두 컴파일러에 따라 다름), 최적화 대문자의 정교함.연구

또 다른 코드 조각 : 아무것도

class A 
{ 
private: 
    int c; 

public: 
    A(int b) 
    { 
     *this = b; 
    } 
    A& operator = (int b) 
    { 
     c = b; 
     return *this; 
    } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int b = 0; 
    A a = b; 
    a = b; 
    a = b; 
    return 0; 
} 

비주얼 스튜디오 2010 최적화 스트립 모든 코드, '전체 최적화'_tmain 빌드 릴리스는 아무것도하지 않고 즉시 0을 반환합니다.

-1

내가 그렇게 많이 C++를 잘 모릅니다하지만 현재 여기

코드 최적화에 자신의 섹션에서 조각입니다 컴파일러 - 원칙, 기법 및 도구를 읽고있다 :

기계 독립적 인 코드 최적화 단계 중간 코드를 개선하여 더 나은 대상 코드가 생성되도록 시도합니다. 일반적으로 은 더 빠르다는 것을 의미하지만 짧은 코드 또는 적은 전력을 소비하는 대상 코드와 같은 다른 목표가 필요할 수도 있습니다. 예를 들어, 직접 알고리즘은 을 사용하여 의미 체계 분석기의 트리 표현의 각 연산자에 대한 명령어를 사용하여 중간 코드 (1.3)를 생성합니다. 간단한 중간 코드 생성 알고리즘 다음에 코드 최적화를 수행하면 이 좋은 목표 코드를 생성하는 데 합리적인 방법입니다. optimizer는 을 정수에서 부동 소수점으로 1 회 변환하고 을 모두 컴파일 타임으로 생성 할 수 있으므로 inttofloat 연산은 정수 6을 부동 소수점 수 60.0으로 바꾸어 을 제거 할 수 있습니다. 또한 T3 그래서 최적화 프로그램이 짧은 순서 (1.4)

1.3 
t1 - intoffloat(60 
t2 -- id3 * id1 
ts -- id2 + t2 
id1 t3 

1.4 
t1=id3 * 60.0 
id1 = id2 + t1 

모두에 1.3를 변환 할 수 있습니다 ID1하는 값을 trasmit 한 번만 사용하고, 내 말은 모두 그 코드 최적화가에 와야 말 코드가 그렇게 단순한 상태에 있기 때문에 코드가 수행하는 효과가 없습니다.

0

최적화는 "복사 또는 할당 호출을 제거하지 않습니다." 유한 상태 기계를 다른 유한 상태, 기계와 동일한 외부 동작으로 변환합니다.

지금, 당신은 repeadly 컴파일러가하는 일

a=b; a=b; a=b; 

를 호출하면 것은 operator=이 실제로 무엇인지에 따라 달라집니다. 컴파일러가 호출 상태가 프로그램 상태를 변경할 기회가 없다는 사실을 발견하면 ("프로그램 상태"는 "스코프가 액세스 할 수있는 범위보다 오래갑니다") 컴파일러는이를 제거합니다. "시연"할 수없는 경우 통화가 그대로 유지됩니다.

컴파일러가 어떤 작업을 수행하든 관계없이 컴파일러는 (계약에 따라) 프로그램이나 그 일부의 외부 논리를 변경할 수 없습니다.

-1

const 변수 및 const_cast에 몇 가지 문제가 있습니다. 컴파일러가 다른 것을 계산할 때 잘못된 결과를 생성했습니다. const 변수는 최적화 된 상태로 유지되었으며 이전 값은 컴파일 타임 상수로 만들어졌습니다. 정말 "예기치 않은 행동".좋아, 아마하지)

예 :

const int x = 2; 
const_cast<int&>(x) = 3; 
int y = x * 2; 
cout << y << endl; 
+0

아무 것도 예상치 못한 일입니다. 'const_cast'는 참조 또는 포인터의'const'ness,'const'라고 선언되지 않은 객체 (예 : 잘못된 API를 다루거나'operator' 호출 쌍을 정의하는 단축키를 사용할 때)를 던지기위한 것입니다. 대조적으로,이 표준은 원래'const'라고 선언 된 변수의'const'ness를 캐스팅하는 것이 정의되지 않은 행동이라는 것을 매우 신중하게 주장합니다. –