2013-04-10 77 views
1

如果我可以测量特定线程所采用的实际时间或cpu刻度,C/Linux中的线程执行时间

pthreadcreate(.........); 
// 
// 
pthreadjoin(.......); 

我正在运行3个主题。

一个主线程正在调用其余两个线程。 我想测量一个被调用线程的执行时间。

我应该在linux环境下使用什么?

+0

想这一个..? http://www.daniweb.com/software-development/cpp/threads/201513/how-to-get-a-threads-execution-time – 2013-04-10 09:26:30

+0

谢谢Hiren, 寻找更多调谐结果,以微秒为单位.. – San 2013-04-10 09:29:18

+0

尝试在线程入口/出口处使用'clock_gettime(CLOCK_THREAD_CPUTIME_ID,...)'(你可以在你的'pthread_create'入口点使用包装器函数来避免改变多个线程函数 – Useless 2013-04-10 10:05:56

回答

0

你可以在开始做一件事

在线程函数使用最多的printk进行日志。你可以用不同的线程分开它,thread_t变量或线程索引

并且在该线程函数的末尾放置另一个类似的日志。

所以在dmesg

会显示日志与timestamp

这样你就可以区分结束日志的时间与开始时间日志。

我知道这不是更实际的做法,但仅仅为了调试目的,您可以毫不费力地做到这一点。

+0

看起来不错!! 我已经用同样的方法做了 进一步寻找更好的方法/清晰度!! – San 2013-04-10 09:45:39

+0

为什么在内核空间中使用printk?printk,并且没有pthread。是k线程,并且与pthread完全不同。dmesg将会工作ñ。尝试收集时间thrad开始和结束可能会有用的结果。因为程序可能永远不会使用pthread_join,如果它们不需要的话。我们经常需要与程序一样长的线程。 – 2013-04-10 10:41:29

+0

@rr_ovi yea在这里可以很好地捕获op在内核空间中的需求,所以不需要pthread。 – 2013-04-10 11:27:59

0

如果你想有一个更准确的结果,您可以使用刻度计数器:

#ifndef TIMING_H 
#define TIMING_H 

/* 
* -- Init timing library with timing_init(); 
* -- get timestamp : 
* tick_t t; 
* GET_TICK(t); 
* -- get delay between two timestamps in microseconds : 
* TIMING_DELAY(t1, t2); 
*/ 

#include <sys/time.h> 
#include <unistd.h> 
#include <stdint.h> 

#ifndef min 
#define min(a,b) \ 
    ({__typeof__ ((a)) _a = (a); \ 
     __typeof__ ((b)) _b = (b); \ 
     _a < _b ? _a : _b; }) 
#endif 

typedef union u_tick 
{ 
    uint64_t tick; 

    struct 
    { 
    uint32_t low; 
    uint32_t high; 
    } 
    sub; 
} tick_t; 

static double scale_time = 0.0; 
static unsigned long long residual = 0; 

#if defined(__i386__) || defined(__pentium__) || defined(__pentiumpro__) || defined(__i586__) || defined(__i686__) || defined(__k6__) || defined(__k7__) || defined(__x86_64__) 
# define GET_TICK(t) __asm__ volatile("rdtsc" : "=a" ((t).sub.low), "=d" ((t).sub.high)) 
#else 
# error "Unsupported processor" 
#endif 

#define TICK_RAW_DIFF(t1, t2) ((t2).tick - (t1).tick) 
#define TICK_DIFF(t1, t2) (TICK_RAW_DIFF(t1, t2) - residual) 
#define TIMING_DELAY(t1, t2) tick2usec(TICK_DIFF(t1, t2)) 

void timing_init(void) 
{ 
    static tick_t t1, t2; 
    int i; 

    residual = (unsigned long long)1 << 63; 

    for(i = 0; i < 20; i++) 
    { 
     GET_TICK(t1); 
     GET_TICK(t2); 
     residual = min(residual, TICK_RAW_DIFF(t1, t2)); 
    } 

    { 
    struct timeval tv1,tv2; 

    GET_TICK(t1); 
    gettimeofday(&tv1,0); 
    usleep(500000); 
    GET_TICK(t2); 
    gettimeofday(&tv2,0); 
    scale_time = ((tv2.tv_sec*1e6 + tv2.tv_usec) - 
     (tv1.tv_sec*1e6 + tv1.tv_usec))/
     (double)(TICK_DIFF(t1, t2)); 
    } 
} 

double tick2usec(long long t) 
{ 
    return (double)(t)*scale_time; 
} 

#endif /* TIMING_H */