为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Linux中创建高分辨率计时器以测量程序性能?

/ 猿问

如何在Linux中创建高分辨率计时器以测量程序性能?

MMMHUHU 2019-11-14 15:24:46

我正在尝试比较GPU与CPU的性能。对于NVIDIA GPU,我一直在使用这些cudaEvent_t类型来获得非常精确的时间。


对于CPU,我一直在使用以下代码:


// Timers

clock_t start, stop;

float elapsedTime = 0;


// Capture the start time


start = clock();


// Do something here

.......


// Capture the stop time

stop = clock();

// Retrieve time elapsed in milliseconds

elapsedTime = (float)(stop - start) / (float)CLOCKS_PER_SEC * 1000.0f;

显然,这段代码只有在您数秒的情况下才是好的。而且,结果有时出来很奇怪。


有谁知道在Linux中创建高分辨率计时器的某种方法?


查看完整描述

3 回答

?
慕容森

签出clock_gettime,这是高分辨率计时器的POSIX接口。


如果已经阅读手册页,留给你想知道的区别CLOCK_REALTIME和CLOCK_MONOTONIC,看到CLOCK_REALTIME和CLOCK_MONOTONIC之间的区别?


有关完整的示例,请参见以下页面:http : //www.guyrutenberg.com/2007/09/22/profiling-code-using-clock_gettime/


#include <iostream>

#include <time.h>

using namespace std;


timespec diff(timespec start, timespec end);


int main()

{

    timespec time1, time2;

    int temp;

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);

    for (int i = 0; i< 242000000; i++)

        temp+=temp;

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

    cout<<diff(time1,time2).tv_sec<<":"<<diff(time1,time2).tv_nsec<<endl;

    return 0;

}


timespec diff(timespec start, timespec end)

{

    timespec temp;

    if ((end.tv_nsec-start.tv_nsec)<0) {

        temp.tv_sec = end.tv_sec-start.tv_sec-1;

        temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;

    } else {

        temp.tv_sec = end.tv_sec-start.tv_sec;

        temp.tv_nsec = end.tv_nsec-start.tv_nsec;

    }

    return temp;

}


查看完整回答
反对 回复 2019-11-14
?
慕运维1137616

总结到目前为止提供的信息,这是典型应用程序所需的两个功能。


#include <time.h>


// call this function to start a nanosecond-resolution timer

struct timespec timer_start(){

    struct timespec start_time;

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);

    return start_time;

}


// call this function to end a timer, returning nanoseconds elapsed as a long

long timer_end(struct timespec start_time){

    struct timespec end_time;

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);

    long diffInNanos = (end_time.tv_sec - start_time.tv_sec) * (long)1e9 + (end_time.tv_nsec - start_time.tv_nsec);

    return diffInNanos;

}

这是一个示例,说明如何使用它们来计时输入列表的方差所需的时间。


struct timespec vartime = timer_start();  // begin a timer called 'vartime'

double variance = var(input, MAXLEN);  // perform the task we want to time

long time_elapsed_nanos = timer_end(vartime);

printf("Variance = %f, Time taken (nanoseconds): %ld\n", variance, time_elapsed_nanos);


查看完整回答
反对 回复 2019-11-14
?
大话西游666

阅读此线程后,我开始针对c ++ 11的chrono测试clock_gettime的代码,它们似乎不匹配。


他们之间有很大的差距!


所述的std ::计时::秒(1)似乎是相当于〜30000的的clock_gettime


#include <ctime>

#include <cstdlib>

#include <cstring>

#include <iostream>

#include <thread>

#include <chrono>

#include <iomanip>

#include <vector>


timespec diff(timespec start, timespec end);

timespec get_cpu_now_time();

std::vector<timespec> get_start_end_pairs();

void output_deltas(const std::vector<timespec> &start_end_pairs);


//=============================================================

int main()

{

    std::cout << "Hello waiter" << std::endl; // flush is intentional

    std::vector<timespec> start_end_pairs = get_start_end_pairs();

    output_deltas(start_end_pairs);


    return EXIT_SUCCESS;

}


//=============================================================

std::vector<timespec> get_start_end_pairs()

{

    std::vector<timespec> start_end_pairs;

    for (int i = 0; i < 20; ++i)

    {

        start_end_pairs.push_back(get_cpu_now_time());

        std::this_thread::sleep_for(std::chrono::seconds(1));

        start_end_pairs.push_back(get_cpu_now_time());

    }


    return start_end_pairs;

}


//=============================================================

void output_deltas(const std::vector<timespec> &start_end_pairs)

{

    for (auto it_start = start_end_pairs.begin(); it_start != start_end_pairs.end(); it_start += 2)

    {

        auto it_end = it_start + 1;

        auto delta = diff(*it_start, *it_end);


        std::cout

            << "Waited ("

            << delta.tv_sec

            << "\ts\t"

            << std::setw(9)

            << std::setfill('0')

            << delta.tv_nsec

            << "\tns)"

            << std::endl;

    }

}


//=============================================================

timespec diff(timespec start, timespec end)

{

    timespec temp;

        temp.tv_sec = end.tv_sec-start.tv_sec;

        temp.tv_nsec = end.tv_nsec-start.tv_nsec;


        if (temp.tv_nsec < 0) {

        ++temp.tv_sec;

        temp.tv_nsec += 1000000000;

    }

    return temp;

}


//=============================================================

timespec get_cpu_now_time()

{

    timespec now_time;

    memset(&now_time, 0, sizeof(timespec));

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now_time);


    return now_time;

}

输出:


Waited (0   s   000064802   ns)

Waited (0   s   000028512   ns)

Waited (0   s   000030664   ns)

Waited (0   s   000041233   ns)

Waited (0   s   000013458   ns)

Waited (0   s   000024068   ns)

Waited (0   s   000027591   ns)

Waited (0   s   000028148   ns)

Waited (0   s   000033783   ns)

Waited (0   s   000022382   ns)

Waited (0   s   000027866   ns)

Waited (0   s   000028085   ns)

Waited (0   s   000028012   ns)

Waited (0   s   000028172   ns)

Waited (0   s   000022121   ns)

Waited (0   s   000052940   ns)

Waited (0   s   000032138   ns)

Waited (0   s   000028082   ns)

Waited (0   s   000034486   ns)

Waited (0   s   000018875   ns)


查看完整回答
反对 回复 2019-11-14

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信