首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在重复调用clock_gettime时会看到400倍的异常计时?

问为什么在重复调用clock_gettime时会看到400倍的异常计时?
EN

Stack Overflow用户
提问于 2018-03-10 03:20:37
回答 2查看 852关注 0票数 7

我正在尝试使用物理时钟来测量c++中某些命令的执行时间,但我遇到了一个问题,即从计算机上的物理时钟读取测量值的过程可能需要很长时间。代码如下:

代码语言:javascript
复制
#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告诉我的),以避免任何进程被调度器移到后台的问题:

代码语言:javascript
复制
$ taskset -c 20 ./a.out

这是我得到的结果:

代码语言:javascript
复制
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稍大一些),还有什么会导致这些“减速”(因为没有更好的名称)?

EN

回答 2

Stack Overflow用户

发布于 2018-03-10 04:21:56

taskset命令定义您的进程的亲和性,这意味着您的进程被限制为只能在指定的CPU核心上运行。它不会以任何方式限制其他进程,这意味着它们中的任何一个都可以在任何时候抢占您的进程(因为它们都允许在您为您的进程选择的CPU核心上运行)。因此,您的最大读取时间间隔( 5-25微秒)可能代表CPU上的其他进程或中断运行时间加上上下文切换时间。此外,您还应该使用CLOCK_REALTIME (或特定于linux的CLOCK_MONOTONIC_RAW)来测量时间间隔,它可能会受到NTP的影响。

票数 3
EN

Stack Overflow用户

发布于 2018-03-10 04:05:09

这在现代c++中要容易得多。

代码语言:javascript
复制
#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个时钟周期。

票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49200725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档