我试图获取特定代码段的执行时间(可能是循环或函数等)。我听说命令time
或函数clock()
完成了这项工作。但我的要求是毫秒/微秒的准确度。所以我写了这样的东西。
int main()
{
struct timeval ts1, ts2;
long long time1, time2, diff;
int i,var;
scanf("%d",&var);
gettimeofday(&ts1, NULL);
time1 = (ts1.tv_sec * 1000000) + ts1.tv_usec;
for (i=0; i<var; i++); // <-- Trying to measure execution time for the loop
gettimeofday(&ts2, NULL);
time2 = (ts2.tv_sec * 1000000) + ts2.tv_usec;
printf("-------------------------\n");
diff = time2 - time1;
printf("total %ld microseconds\n", diff);
printf("%ld seconds\n", diff/1000000);
diff %= 1000000;
printf("%ld milliseconds\n", diff/1000);
diff %= 1000;
printf("%ld microseconds\n", diff);
printf("-------------------------\n");
return 0;
}
我有两个问题
感谢您的帮助!感谢。
答案 0 :(得分:1)
您显示的上述代码是为了获得自gettimeofday()
返回挂钟时间以来的实际时间。至于不使用优化级别-O2,请将i声明为volatile int i
,这将阻止优化到i
。
答案 1 :(得分:1)
这个NanoTimer类(头文件)应该可以完成这项工作。 使用startTimer()/ stopTimer()。请注意,计算此相对分辨率的已用时间需要一段时间,因此如果只执行startTimer(),则永远不会有0值; stopTimer();中间没有任何代码。 此外还有许多其他因素会影响已用时间,因此您应多次重复特定度量并取最低值。
class NanoTimer
{
struct timespec ts_;
u_int64_t startTimer_;
u_int64_t totalTimer_;
public:
NanoTimer()
{
totalTimer_ = 0;
startTimer_ = 0;
}
u_int64_t getNanoSecTimer(void)
{
clock_gettime(CLOCK_REALTIME, &ts_);
return ts_.tv_sec * 1000000000 + ts_.tv_nsec;
}
void startTimer(void)
{
startTimer_ = getNanoSecTimer();
}
void stopTimer(void)
{
//assert(startTimer_ > 0);
totalTimer_ += getNanoSecTimer() - startTimer_;
startTimer_ = 0;
}
inline u_int32_t getTotalSeconds()
{
return totalTimer_/1000000000;
}
inline u_int32_t getTotalMilliseconds()
{
return totalTimer_/1000000;
}
inline u_int32_t getTotalMicroseconds()
{
return totalTimer_/1000;
}
inline u_int32_t getTotalNanoseconds()
{
return totalTimer_;
}
inline u_int32_t getCurrentSeconds()
{
return (totalTimer_ + (startTimer_ > 0 ? getNanoSecTimer() - startTimer_ : 0)) / 1000000000;
}
};
答案 2 :(得分:0)
您可以使用示例代码!!该代码导致计算成本无开销
#include <sys/time.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>
void timing(double* wcTime, double* cputime)
{
struct timeval tp;
gettimeofday(&tp, NULL);
*wcTime=(double) (tp.tv_sec + tp.tv_usec/1000000.0);
struct rusage ruse;
getrusage(RUSAGE_SELF, &ruse);
*cpuTime=(double)(ruse.ru_utime.tv_sec+ruse.ru_utime.tv_usec / 1000000.0);
}
使用:
double wcs, // Wall Clock Start
wce, // Wall Clock End
ccs, // CPU Clock Start
cce; // CPU Clock End
timing(&wcs, &ccs);
// COMPUTATION CODE
timing(&wce, &cce);
cout << "CPU RUNTIME: " << cce - ccs << endl
<< "WALL CLOCK TIME: " << wce - wcs << endl;
答案 3 :(得分:0)
可变速率CPU时钟和热余量的利用使我越来越怀疑,对于运行时间不够长以加热核心的功能而言,挂钟时间以秒为单位可能不如循环计数有用。
如果我正在使用我自己的代码,我倾向于选择以下内容:
static __inline__ uint64_t rdtsc(void)
{
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 );
}
使用它,我可以在函数调用之前和之后记录TSC值,减去这两个值,并获得所花费的周期数。
如果您需要挂钟时间,可以使用clock_gettime()
中的time.h
,如果不准确,将为您提供纳秒分辨率,并使用以下内容减去两者(之前和之后){{ 1}}对象:
struct timespec
那就是说,我倾向于使用#define NSEC_PER_SEC 1000000000
static int timespec_subtract(result, x, y)
struct timespec *result, *x, *y;
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_nsec < y->tv_nsec) {
int nsec = (y->tv_nsec - x->tv_nsec) / NSEC_PER_SEC + 1;
y->tv_nsec -= NSEC_PER_SEC * nsec;
y->tv_sec += nsec;
}
if (x->tv_nsec - y->tv_nsec > NSEC_PER_SEC) {
int nsec = (x->tv_nsec - y->tv_nsec) / NSEC_PER_SEC;
y->tv_nsec += NSEC_PER_SEC * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_nsec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_nsec = x->tv_nsec - y->tv_nsec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}
并完全避免使用仪器。