2010-01-19 1 views
4

프로파일 링을하기 위해 C에서 스코프 가드를 사용하고 싶습니다.C의 스코프 가드

나는 함수에서 소비 한 시간을 알고 싶습니다. 여기 내가하는 일이 있습니다 :

int function() { 

    tic(); 

    ... do stuff ... 
    if (something) 
    { 
    toc(); 
    return 0; 
    } 

    toc(); 
    return 1; 
} 

나는이 기능을 종료 할 때마다 toc 문을 써야합니다. 어디서나 붙여 넣기를 복사하지 않고도하고 싶습니다. 매크로 또는 무언가를 사용하여이를 수행하는 일반적인 방법이 있습니까? 또한 프로필해야하는 많은 기능이 있으므로 함수를 호출하는 방식을 변경하고 싶지 않습니다.

감사

답변

5

이것은 함수 호출 방식을 변경하지 않습니다. 당신이 모든 단일 기능을 프로파일 링 할 수 있기를 원한다면 아마도별로 사용하지 않을 것입니다.

static inline int real_function() { 
    // previous contents of function(), with no tic or toc 
} 

int function() { 
    tic(); 
    int r = real_function(); 
    toc(); 
    return r; 
} 

다른 사람들처럼 프로파일 러를 사용하면 장기적으로 많은 노력을 절약 할 수 있습니다. 그들은 말하지 않기 때문에 : 플랫폼에 플랫폼이있는 경우.

그렇다면 가장 쉬운 방법은 (코딩 규칙으로) 함수에 하나의 종료점 만 있어야하며 종료점은 매크로를 통해 수행해야한다는 것입니다. 그런 다음 입력 및 종료시 코드로 모든 기능을 수동으로 계측 할 수 있습니다. 다중 리턴을 가진 레거시 함수는 위와 같이 래핑 될 수 있습니다.

또한 컴파일러에서 처리 할 때 염두에 두어야 할 점이 있습니다. 이 작업을 작성할 수 있습니다

tic(); 
do_something(); 
int i = something_else(); 
toc(); 
return i; 

을 컴파일러는 다음 something_else 상당한 시간이 소요에도 불구하고, 그것은이에 코드를 켤 수도, 어떤 부작용을 something_else이 없다고 판단하는 경우 :

tic(); 
do_something(); 
toc(); 
return something_else(); 

그리고 당신의 프로필 데이터는 귀하의 기능에 소비 된 시간을 과소 평가합니다. 실제 프로파일 러를 사용하는 것이 매우 좋은 또 다른 이유는 컴파일러와 협력 할 수 있기 때문입니다.

4

당신은 같은 매크로를 정의 할 수 있습니다 : 어디서나 당신이 그것을 넣어 작동합니다

#define TOC_RETURN(x) \ 
    do { \ 
    toc(); \ 
    return x; \ 
    } while(0) 

. 그런 다음 return *;TOC_RETURN(*)으로 바꾸는 작업을 자동화 할 수 있습니다.

+0

이것은 작성할 수 없습니다. – einpoklum

0

흠, 어쩌면 매크로 (매크로 제품군)에서 함수 호출을 래핑 할 수 있습니까? 당신은 RETVAL void를 반환 버전으로, 당신이 만드는 함수 호출의 각 인수에 대응하기위한 매크로가 필요합니다

// define the wrapper for name 
#define DEFTIMECALL0(Retval,name) \ 
    Retval timed##name() \ 
    { \ 
     Retval ret; 
     tic(); \ 
     ret = name(); \ 
     toc(); \ 
     return ret; \ 
    } 

: 여기에 RETVAL를 인수를 취하지 않고 반환 하나입니다.

편집는 어쩌면 단지 (각 인수에 대응하기위한, 다시 입력/무효 버전을 반환) 매크로의 가족을 가지고 심지어 래퍼 함수를 ​​정의하는 점, 그리고 더 나은 존재하지 않은 랩 A의 함수 호출을 tic/toc 직접 callites에서

계측 프로파일 러를 두려워하지 마십시오.

1

매크로를 권장하지 않습니다. 코드를 한 번만 프로파일 링하고 'return'을 그 목적을위한 몇 가지 특수 매크로로 바꾸면 코드를 읽기 쉽게 만듭니다.

다음과 같이하는 것이 좋지 않습니까?

tic(); 
call_function(); 
toc(); 

이것은 자동으로 기능에서 "모든 종료점"을 처리합니다.

P. 왜 프로파일 러를 사용하지 않습니까?

1

실제 프로파일 러는 프로파일 링이 활성화 된 상태에서 컴파일하기 위해 코드를 수정할 필요가 없습니다.

4

gprof과 같은 실제 프로파일 링 도구를 사용하지 않는 이유는 무엇입니까?

+0

gprof가 C 표준의 일부가 아닙니다 .-) –

+0

혼란을 피하기 위해 문구가 변경되었습니다. :) – jamessan

1

당신은 "재정의"매크로를 통해 반환 할 수 있습니다 : (면책 조항 참조)

#include <stdio.h> 

void tic() { printf("tic\n"); } 
void toc() { printf("toc\n"; } 

#define return toc(); return 
int foo() { 
    tic(); 

    return 0; 
} 
#undef return 

int main() { 
    foo(); 
    return 0; 
} 

면책 조항 : 때문이 추하고 해키 간주 될 수 있습니다 : 그것은 원

  • 당신이 반환을 사용하지 않으면 무효 함수에 대한 작업을하지 않습니다;- 명언.
  • MSVC8에서 작동하더라도 휴대용/표준이 아닐 수 있습니다.
  • 키워드를 정의해서는 안됩니다.
+1

이것은 하루 종일 보았던 C의 가장 아름다운 남용입니다! – f3xy