2017-08-15 18 views
-2

在下面的代码中,如何测量总经过时间function1()function3()C++测量重复调用的函数的时间

在实际情况中,function1()function3()散落在复杂的程序中的任何地方。我需要一些可以使用函数名称来启动和停止一个timer,所以最终我可以打印出每个函数总共需要多长时间。

请注意,所需的时间不是所需的时间,而是function1()总计时间贬值function1()这是所谓的无处不在多次是需要的价值。

int function1() 
{ 
    int i = 1; 
    i++; 
    return i; 
} 
int function2() 
{ 
    int i = 1; 
    i++; 
    return i; 
} 
int function3() 
{ 
    int i = 1; 
    i++; 
    return i; 
} 
int main(int argc, char *argv[]) 
{ 
    size_t t = 0; 

    while (t < 1000000) 
    { 
     // I want something like startTimer(function1) 
     function1(); 
     // I want something like pauseTimer(function1) 
     function2(); 
     // I want something like startTimer(function3) 
     function3(); 
     // I want something like pauseTimer(function3) 
    } 
    // printTimer() here will print the total elapsed time of function 1 and 
    //function 3 
    getchar(); 
    return 0; 
} 
+2

除了你的例子甚至没有编译,你有没有尝试过任何东西?我不明白什么是问题。你可以使用'std :: chrono'中的函数来实现这个功能。 – user0042

+0

对不起。代码不是我写的,而是我面对的真实情况的反映。我编辑过它来编译它。我使用std :: map进行定时器管理,但开销太大。我确实在核心部分使用了std :: chrono。当发生一次功能时,很容易测量单个功能的时间。当功能分散到各处并且我必须测量总时间时很困难 –

+4

您可能需要一个分析工具。 – user0042

回答

1

运行探查可能是做到这一点的最好办法,但如果你不能这样做,因为某些原因,你可以做到以下几点:

1)临时重命名功能1()的执行到例如function1_implementation()(或类似)

2)写一个新的临时执行功能1()是这样的:

static unsigned long long totalMicrosInFunction1 = 0; 

// Returns current system-clock-time, in microseconds 
static unsigned long long get_current_time_in_microseconds() 
{ 
    // This may not be the best way to implement this function; see below 
    struct timeval tv; 
    gettimeofday(&tv, NULL); 
    return ((unsigned long long)tv.tv_sec)*1000000 + tv.tv_usec; 
} 

int function1() 
{ 
    unsigned long long startTime = get_current_time_in_microseconds(); 
    int ret = function1_implementation(); // call the real code! 
    unsigned long long endTime = get_current_time_in_microseconds(); 

    totalMicrosInFunction1 += (endTime-startTime); 
    return ret; 
} 

3)做同样的伎俩对于要时间的任何其他职责。

...然后重新编译你的程序,并在main()结尾处打印出totalMicrosInFunction1的当前值。

请注意,上述get_current_system_time_in_microseconds()的实现可能不是您用例的最佳实现;如果您使用C++ 11,则可以使用std::chrono::high_resolution_clock来代替此目的;否则你可以在windows下使用特定于操作系统的API,例如QueryPerformanceCounter()

+0

如果我使用时间分析工具,当我的程序有超过1000个功能,并且那里只有10个我感兴趣的功能,我可以选择仅查看这10个功能吗?大概; –

+0

大概;它当然取决于你使用的工具。 –

1

假设您使用单个CPU模块在PC上运行,您可以使用rdtscp指令并获取滴答数。积累蜱虫。完成后,将刻度转换为时间,然后完成。

看链接:https://msdn.microsoft.com/en-us/library/bb385235.aspx如何在Windows上执行rdtscp。

这是假设你只有一个线程。

现在,创建一个变量“unsigned __int64 totalTicks = 0;”在文件范围。

功能1将被写为如下:

int function1() 
{ 
    unsigned int arg; 
    unsigned __int64 startTicks = __rdtscp(&arg); // arg is not used 
    int ret = function1_implementation(); // call the real code! 
    unsigned __int64 endTicks = __rdtscp(&arg); 
    totalTicks += (endTicks - startTicks); 

    return ret; 
} 

Tick是CPU时钟速率的倒数,所以2.5GHz的CPU将具有在每秒2.5十亿蜱。

或者,您可以创建一个Timer类,它具有我描述的核心功能 - 创建start()和stop()方法以返回两个值,并使用elapsed()方法返回delta。在任何函数的开头调用start(),并在结尾调用elapsed()。然后,任何需要唯一定时器的函数都可以使用不同的Timer实例。

这会给现代CPU带来亚纳秒的分辨率。如果你的功能小而快,使用单调时间答案可能不会给你足够的分辨率。这也是使用分析器的问题,因为它们通常以10ms的时钟速率(Linux上的gprof)进行统计学取样,所以您将得到准确的计数,但只能估计所花费的时间。