我正在尝试使用物理时钟来测量c++中某些命令的执行时间,但我遇到了一个问题,即从计算机上的物理时钟读取测量值的过程可能需要很长时间。代码如下:
#include <string>
#include <cstdlib>
#include <iostream>
#include <math.h>
#include <time.h>
int main()
{
int64_t mtime, mtime2, m_TSsum, m_TSssum, m_TSnum, m_TSmax;
struct timespec t0;
struct timespec t1;
int i,j;
for(j=0;j<10;j++){
m_TSnum=0;m_TSsum=0; m_TSssum=0; m_TSmax=0;
for( i=0; i<10000000; i++) {
clock_gettime(CLOCK_REALTIME,&t0);
clock_gettime(CLOCK_REALTIME,&t1);
mtime = (t0.tv_sec * 1000000000LL + t0.tv_nsec);
mtime2= (t1.tv_sec * 1000000000LL + t1.tv_nsec);
m_TSsum += (mtime2-mtime);
m_TSssum += (mtime2-mtime)*(mtime2-mtime);
if( (mtime2-mtime)> m_TSmax ) { m_TSmax = (mtime2-mtime);}
m_TSnum++;
}
std::cout << "Average "<< (double)(m_TSsum)/m_TSnum
<< " +/- " << floor(sqrt( (m_TSssum/m_TSnum - ( m_TSsum/m_TSnum ) *( m_TSsum/m_TSnum ) ) ) )
<< " ("<< m_TSmax <<")" <<std::endl;
}
}接下来,我在一个专用的核心上运行它(或者sysadmin告诉我的),以避免任何进程被调度器移到后台的问题:
$ taskset -c 20 ./a.out这是我得到的结果:
Average 18.0864 +/- 10 (17821)
Average 18.0807 +/- 8 (9116)
Average 18.0802 +/- 8 (8107)
Average 18.078 +/- 6 (7135)
Average 18.0834 +/- 9 (21240)
Average 18.0827 +/- 8 (7900)
Average 18.0822 +/- 8 (9079)
Average 18.086 +/- 8 (8840)
Average 18.0771 +/- 6 (5992)
Average 18.0894 +/- 10 (15625)显然,调用clock_gettime()大约需要18纳秒(在这个特定的服务器上),但是我不能理解为什么“最大”时间似乎要长300到1000倍?
如果我们假设内核真的专用于这个进程,而不是被其他东西使用(这可能是真的,也可能不是;当不是在专用的内核上运行时,平均时间是相同的,但sd/max稍大一些),还有什么会导致这些“减速”(因为没有更好的名称)?
发布于 2018-03-10 04:21:56
taskset命令定义您的进程的亲和性,这意味着您的进程被限制为只能在指定的CPU核心上运行。它不会以任何方式限制其他进程,这意味着它们中的任何一个都可以在任何时候抢占您的进程(因为它们都允许在您为您的进程选择的CPU核心上运行)。因此,您的最大读取时间间隔( 5-25微秒)可能代表CPU上的其他进程或中断运行时间加上上下文切换时间。此外,您还应该使用CLOCK_REALTIME (或特定于linux的CLOCK_MONOTONIC_RAW)来测量时间间隔,它可能会受到NTP的影响。
发布于 2018-03-10 04:05:09
这在现代c++中要容易得多。
#include <chrono>
auto start = std::chrono::steady_clock::now();
.....
auto stop = std::chrono::steady_clock::now();
auto duration = stop - start;对于非实时操作系统来说,18纳秒是相当快的。你真的需要测量比这更精确的东西吗?根据我的计算,在4 4GHz的CPU上,18 is只有72个时钟周期。
https://stackoverflow.com/questions/49200725
复制相似问题