Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 扩展std::chrono功能以处理运行时(非编译时)常量周期_C++_Time - Fatal编程技术网

C++ 扩展std::chrono功能以处理运行时(非编译时)常量周期

C++ 扩展std::chrono功能以处理运行时(非编译时)常量周期,c++,time,C++,Time,我一直在Linux和OSX上试验各种定时器,我想尝试用std::chrono使用的相同接口包装其中的一些定时器 对于在编译时具有定义良好的“周期”的计时器来说,这很容易做到,例如POSIX clock_gettime()系列、OSX上的clock_get_time()系列或gettimeofday() 然而,有些有用的计时器的“周期”——虽然是常量——只有在运行时才知道。 例如: -POSIX说明了时钟()的周期,即每秒时钟数,在非XSI系统上可能是一个变量 -在Linux上,时间段()在运行时

我一直在Linux和OSX上试验各种定时器,我想尝试用std::chrono使用的相同接口包装其中的一些定时器

对于在编译时具有定义良好的“周期”的计时器来说,这很容易做到,例如POSIX clock_gettime()系列、OSX上的clock_get_time()系列或gettimeofday()

然而,有些有用的计时器的“周期”——虽然是常量——只有在运行时才知道。 例如: -POSIX说明了时钟()的周期,即每秒时钟数,在非XSI系统上可能是一个变量 -在Linux上,时间段()在运行时由sysconf(_SC_CLK_TCK)给出 -在OSX上,马赫数绝对时间()的周期在运行时由马赫数时基信息()给出 -在最近的英特尔处理器上,DST寄存器以恒定速率进行计时,但这当然只能在运行时确定

要在std::chrono接口中封装这些计时器,一种可能是使用std::chrono::纳秒的周期,并将每个计时器的值转换为纳秒。另一种方法是使用浮点表示。但是,这两种方法都会给now()函数带来(非常小的)开销,并且(可能很小的)精度损失

我试图寻求的解决方案是定义一组类来表示这样的“运行时常量”周期,它们是按照与std::ratio类相同的行构建的。 但是,我希望这将需要重写所有相关的模板类和函数(因为它们假定为constexpr值)

我怎样把这种计时器包装成一个标准的计时器

或者对时钟的时间段使用非constexpr值

[是否有人有经验]或在时钟时间段使用非constexpr值

在阅读标准(20.11.5,课程模板持续时间)后,“期间”应为“比率的专门化”:

备注:如果周期不是比率的特化,则程序格式不正确

所有chrono模板都严重依赖constexpr功能

有没有人有过将这种计时器包装成一个标准计时器的经验

我发现了一个建议,使用句点为1的duration,boost::rational作为rep,尽管没有任何具体的例子

有没有人有过包装这种计时器的经验 时间

事实上我喜欢。在OSX上,您感兴趣的平台之一。:-)

你提到:

在OSX上,mach_absolute_time()的周期在运行时由 马赫时基信息()

绝对正确。同样在OSX上,
高分辨率时钟
稳定时钟
的实现实际上是基于
马赫绝对时间
。我是这段代码的作者,这段代码是开源的,有一个慷慨的许可证(只要你保留版权,就可以用它做任何你想做的事情)

这是你的资料来源。它的建造方式和你想象的差不多。运行时间段在返回之前转换为纳秒。在OSX上,转换因子通常为1,代码利用这一事实进行优化。但是,该代码足够通用,可以处理非1转换因子

在第一次调用
now()
时,查询运行时转换因子到纳秒的成本很小。在一般情况下,计算浮点转换因子。在常见情况下(转换因子==1),后续开销是通过函数指针调用的。我发现开销真的很合理

在OSX上,转换因子虽然直到运行时才确定,但仍然是一个常量(即,不会随程序执行而变化),因此只需计算一次


如果你的周期实际上是动态变化的,你需要更多的基础设施来处理这个问题。基本上,您需要积分(微积分)周期与时间曲线,然后计算两个时间点之间的平均周期。这需要持续监控周期随时间的变化,而
并不是合适的工具。这些工具通常是在操作系统级别处理的。

我也做了类似的事情,但只是针对Linux。你找到了密码;您可以随意以任何方式使用代码

我的实施所面临的挑战与您问题中提到的部分重叠。具体而言:

  • 在运行时检索刻度因子(将时钟刻度转换为基于秒的时间单位所需的刻度因子),但仅使用第一次
    now()
    ‡。如果您担心这会导致较小的开销,在测量任何实际间隔之前,可以在启动时调用
    now()
    函数一次。勾号因子存储在静态变量中,这意味着仍然存在一些开销,因为在最低级别上,
    now()
    函数的每次调用都意味着检查静态变量是否已初始化。但是,每次调用
    now()
    ,此开销都是相同的,因此它不应影响测量时间间隔

  • 默认情况下,我不会转换为纳秒,因为在测量相对较长的时间段(例如几秒钟)时,这会导致溢出非常快。这实际上是我不使用boost实现的主要原因。我没有转换为纳秒,而是将基本单位实现为模板参数(在代码中称为
    Precision
    )。我使用C++11中的
    std::ratio
    作为模板参数。例如,我可以选择一个
    时钟
    ,这意味着调用
    now()
    函数将在内部转换为微秒而不是纳秒,这意味着我可以测量几秒或几分钟的周期,而不超过
    #include "util/proctime.hpp"
    
    #include <ratio>
    #include <chrono>
    #include <thread>
    #include <utility>
    #include <iostream>
    
    int main()
    {
      using std::chrono::duration_cast;
      using millisec   = std::chrono::milliseconds;
      using clock_type = rlxutil::combined_clock<std::micro>;
    
      auto tp1 = clock_type::now();
    
      /* Perform some random calculations. */
      unsigned long step1 = 1;
      unsigned long step2 = 1;
      for (int i = 0 ; i < 50000000 ; ++i) {
        unsigned long step3 = step1 + step2;
        std::swap(step1,step2);
        std::swap(step2,step3);
      }
    
      /* Sleep for a while (this adds to real time, but not CPU time). */
      std::this_thread::sleep_for(millisec(1000));
    
      auto tp2 = clock_type::now();
    
      std::cout << "Elapsed time: "
                << duration_cast<millisec>(tp2 - tp1)
                << std::endl;
    
      return 0;
    }
    
    Elapsed time: [user 40, system 0, real 1070 millisec]