2010-06-25 3 views
2

우리는 약간의 기능에 매우 광범위하게 중첩 포인터를 사용할 수 있다고 가정 : 모든 포인터가 확인하고 유효 가정

function (ptr_a_t ptr_a) { 
    ... 
    a = ptr_a->ptr_b->ptr_c->val; 
    b = ptr_a->ptr_b->ptr_c->val; 
    ... 
} 

을 제외하고 성능 저하, 자성 또는 다른주의 문제는 (이 내가 GCC -S와 조사 목적으로 만 작성이 C 파일을() 컴파일

function (ptr_a_t ptr_a) { 
    val = ptr_a->ptr_b->ptr_c->val; 
    ... 
    a = val; 
    b = val; 
    ... 
} 

업데이트 :에 비해 가독성)

GCC를 들어 -S
typedef struct { 
    int val; 
} c_str_t; 

typedef struct { 
    c_str_t *p_c;  
} b_str_t; 

typedef struct { 
    b_str_t *p_b;  
} a_str_t; 

void func (a_str_t *p_a) 
{ 
    int a,b; 

    a = p_a->p_b->p_c->val; 
    b = p_a->p_b->p_c->val; 

    printf("", a,b); 
} 

:

movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, -4(%ebp) 
movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, -8(%ebp) 

GCC -S -O1를 들어

movl 8(%ebp), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl (%eax), %eax 
movl %eax, 8(%esp) 
movl %eax, 4(%esp) 

I는 구조물 내부 휘발성 specificator을 사용하여 관찰 동일. 따라서 중첩 포인터는 강제로 최적화됩니다.

+0

다른 옵션 : a = b = ptr_a-> ptr_b-> ptr_c-> val; – Nyan

답변

2

이들이 동일한 것으로 취급 될지 여부는 구현에 따라 다릅니다. 두 가지 방법으로 코드를 컴파일하고 컴파일러에서 두 경우를 모두 처리하는 방법을 보려면 어셈블리 출력을 검사하십시오.

내가 개발하고있는 임베디드 시스템에서 필자는 "중간"포인터를 추가하고 기능 실행 시간에 상당한 속도 향상을 보았습니다. 필자의 경우, 컴파일러는 매번 처음부터 포인터 체인을 다시 계산하고이를 최적화하지 않았습니다. 컴파일러는 다를 수 있습니다. 실제 방법은 양방향으로 시도하고 실행 시간을 측정하는 것입니다.

+0

맞아. 최적화가 없으면 gcc가 포인터를 다시 계산합니다. 내 업데이트를 참조하십시오. – pmod

2

저는 컴파일러가 gcc와 동일한 코드를 2 개 최적화 할 것이라고 확신합니다.

둘 다 (gcc에서 -S 스위치 사용)에 대한 어셈블러 코드를 생성하고 비교하여 쉽게 확인할 수 있습니다.

3

중급 구조체 멤버 중 일부가 휘도가으로 표시되어 있지 않으면 컴파일러에서 두 예제를 동일하게 처리해야합니다. 두 번째 코드 샘플을 더 깔끔하게 보이기 때문에이 코드 샘플을 선호합니다.

+1

* 그 (것)들은 동등한 것으로 대우해야한다 말한다. 이것이 반드시 발생해야하거나 발생해서는 안된다는 규칙은 없으며, 특정 컴파일러 (그리고 아마도 사용 된 최적화 옵션)에 의존합니다. – bta

+0

첫 번째 경우 두 줄 사이에서 포인터 중 하나가 변경되지 않았는지 최적화 프로그램이 지금 어떻게 할 수 있습니까? – pmod

+2

@Pmod : 무언가가 "휘발성"으로 표시되지 않으면 컴파일러는 함수 중간에서 변수가 자발적으로 변경되지 않는다고 추측 할 수 있습니다. – Karmastan