在 C++ 中为函数计时

Time a function in C++

我想计算一个函数在 C++ 中花费的时间(以毫秒为单位)。

这是我拥有的:

#include<iostream>
#include<chrono>           
using timepoint = std::chrono::steady_clock::time_point;

float elapsed_time[100];

// Run function and count time
for(int k=0;k<100;k++) {

    // Start timer
    const timepoint clock_start = chrono::system_clock::now();

    // Run Function
    Recursive_Foo();

    // Stop timer
    const timepoint clock_stop = chrono::system_clock::now();

    // Calculate time in milliseconds
    chrono::duration<double,std::milli> timetaken = clock_stop - clock_start;
    elapsed_time[k] = timetaken.count();
}

for(int l=0;l<100;l++) {
    cout<<"Array: "<<l<<" Time: "<<elapsed_time[l]<<" ms"<<endl;
}

这可以编译,但我认为多线程阻止它正常工作。输出以不规则的间隔产生时间,例如:

Array: 0 Time: 0 ms
Array: 1 Time: 0 ms
Array: 2 Time: 15.6 ms
Array: 3 Time: 0 ms
Array: 4 Time: 0 ms
Array: 5 Time: 0 ms
Array: 6 Time: 15.6 ms
Array: 7 Time: 0 ms
Array: 8 Time: 0 ms

我需要使用某种互斥锁吗?或者有没有更简单的方法来计算函数执行所需的毫秒数?

编辑

也许人们建议使用 high_resolution_clocksteady_clock,但所有这三个都会产生相同的不规则结果。

此解决方案似乎产生了实际效果:How to use QueryPerformanceCounter? but it's not clear to me why. Also, https://gamedev.stackexchange.com/questions/26759/best-way-to-get-elapsed-time-in-miliseconds-in-windows 效果很好。似乎是 Windows 实施问题。

配置文件代码使用高分辨率计时器,而不是系统时钟;正如您所见,它的粒度非常有限。

http://www.cplusplus.com/reference/chrono/high_resolution_clock/

typedef tp high_resolution_clock::time_point

const tp start = high_resolution_clock::now();
// do stuff
const tp end   = high_resolution_clock::now();

如果您怀疑您应用中的某些其他进程或线程占用了太多 CPU 时间,请使用:

windows

下的 GetThreadTimes

clock_gettime CLOCK_THREAD_CPUTIME_ID 在 linux

测量线程 CPU 执行函数的时间。这将从您的测量时间中排除在分析期间执行其他 threads/processes。

Microsoft 在几微秒内提供了一个漂亮、干净的解决方案,来自:MSDN

#include <windows.h>

LONGLONG measure_activity_high_resolution_timing()
{
    LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
    LARGE_INTEGER Frequency;

    QueryPerformanceFrequency(&Frequency); 
    QueryPerformanceCounter(&StartingTime);

    // Activity to be timed

    QueryPerformanceCounter(&EndingTime);
    ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


    //
    // We now have the elapsed number of ticks, along with the
    // number of ticks-per-second. We use these values
    // to convert to the number of elapsed microseconds.
    // To guard against loss-of-precision, we convert
    // to microseconds *before* dividing by ticks-per-second.
    //

    ElapsedMicroseconds.QuadPart *= 1000000;
    ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;
    return ElapsedMicroseconds.QuadPart;
}