2017-09-27 13 views
6

이입니다 밖으로 최적화 다소 예제 코드와 Casting a function pointer to another type에 대한 설명을 요청 대답은 "좋은"컴파일러는 에게 my_callback_helper() 기능을 최적화 할 수 있어야하지만, 내가 찾은 말한다도우미 기능을

struct my_struct; 
void my_callback_function(struct my_struct* arg); 
void do_stuff(void (*cb)(void*)); 

static void my_callback_helper(void* pv) 
{ 
    my_callback_function(pv); 
} 
int main() 
{ 
    do_stuff(&my_callback_helper); 
} 

https://gcc.godbolt.org IT 및 도우미 기능을 수행 에서 어떤 컴파일러는 항상 just a jump to my_callback_function() (-03) 경우에도 생성되지 가져옵니다

my_callback_helper: 
     jmp  my_callback_function 
main: 
     subq $8, %rsp 
     movl $my_callback_helper, %edi 
     call do_stuff 
     xorl %eax, %eax 
     addq $8, %rsp 
     ret 

제 질문은 : 컴파일러가 도우미를 제거하지 못하게하는 표준이 있습니까?

+0

필자의 경험에 따르면, 컴파일러는 함수 포인터 값을 컴파일 타임에 결정할 수있는 경우에도 함수 포인터 호출을 인라이닝 할 때 성능이 좋지 않은 경향이 있습니다. 'inline' 키워드로 던져 볼 수도 있습니다. 내가 아는 한, 표준에는 최적화를 방해하는 요소는 없습니다. – Lundin

답변

3

이 최적화를 직접적으로 방해하는 표준은 없습니다. 그러나 실제로 "전체 그림"이없는 컴파일러는 항상 가능하지는 않습니다.

주소는 my_callback_helper입니다. 그래서 컴파일러는 어떤 것을 do_stuff이 그것을 모르기 때문에 쉽게 최적화 할 수 없습니다. do_stuff이 정의 된 별도의 모듈에서 컴파일러는 인수 (my_callback_helper) 대신 단순히 my_callback_function을 호출하거나 호출 할 수 있다는 것을 모릅니다. my_callback_helper을 완전히 최적화하려면 컴파일러가 do_stuff의 기능을 알고 있어야합니다. 그러나 do_stuff은 컴파일러가 정의 할 수없는 외부 함수입니다. 따라서 이런 종류의 최적화는 do_stuff에 대한 정의와 모든 용도로 정의를 제공 할 때 발생할 수 있습니다.

+1

컴파일 및 링크 단계에서 링크 시간 최적화 (-flto with GCC)를 사용하여 다시 작성해야합니다. – dbrank0

+0

가능성있는 포인터 비교 때문에 아마도 금지되어 있다고 생각합니다. 'do_stuff()'는받은 포인터를'my_callback_function()'과 비교하려고 시도했을 것입니다. 최적화를 on으로하면, 비교는'my_callback_function == my_callback_helper'라고 말할 것이고, 두 개의 다른 객체가 같은 주소를 갖는 것은 합법적이지 않을 수도 있습니다. 그것이 불법이라면 점프가 제거 될 수 없다는 것이 약간 불행한 것입니다. 어쩌면 fn 캐스트가 정의되지 않고 구현 정의되는 것이 더 나을 것입니다. – PSkocik