0

我正在尝试将现有程序从(本地)现有时间类转换为使用 C++11 中的新时间设施。对于实时处理,如何将 C++11 功能映射到本地时间类中是很清楚的。尚不清楚如何使用 C++11 计时工具来支持非实时模式(例如,“尽可能快地运行批处理模式”、“以四分之一速度运行演示模式”等.) 本土类支持。这是否通过定义clock将挂墙时间正确映射到“播放”速度的特殊 s 来实现?任何帮助表示赞赏,一个例子会很棒。

例如,我将转换的代码具有以下结构

MessageQueue::poll( Seconds( 1 ) );

或者

sleep( Minutes( 2 ) );

Secondsor对象知道Minutes程序运行的速度,以避免必须在各处使用乘法器或转换函数,例如

MessageQueue::poll( PlaybackSpeed * Seconds( 1 ) );

或者

MessageQueue::poll( PlaybackSpeed( Seconds( 1 ) ) );

我希望有可能的是std::chrono::duration通过std::chrono::time_point提供一个自定义的clock.

4

2 回答 2

2

制作自己的时钟是否足够取决于您如何使用您创建的持续时间。例如,如果您想以半速运行,但在某处调用:

std::this_thread::sleep_for(std::chrono::minutes(2));

持续时间不会调整。相反,您需要使用 sleep_until 并提供一个使用“慢”时钟的时间点。但是制作一个运行缓慢的时钟非常容易:

template<typename Clock,int slowness>
struct slow_clock {
    using rep = typename Clock::rep;
    using period = typename Clock::period;
    using duration = typename Clock::duration;
    using time_point = std::chrono::time_point<slow_clock>;

    constexpr static bool is_steady = Clock::is_steady;

    static time_point now() {
        return time_point(start_time.time_since_epoch() + ((Clock::now() - start_time)/slowness));
    }

    static const typename Clock::time_point start_time;
};

template<typename Clock,int slowness>
const typename Clock::time_point
slow_clock<Clock,slowness>::start_time = Clock::now();

从 now() 返回的 time_points 似乎会以相对于您给它的时钟较慢的速度前进。例如,这是一个程序,因此您可以通过以下方式缓慢观察纳秒:

int main() {
    using Clock = slow_clock<std::chrono::high_resolution_clock,500000000>;
    for(int i=0;i<10;++i) {
        std::this_thread::sleep_until(Clock::now()
                                      + std::chrono::nanoseconds(1));
        std::cout << "tick\n";
    }
}

您实现的所有功能,例如MessageQueue::poll(),可能都需要根据全局时钟 typedef 来实现。

当然,这一切都与程序实际运行的速度无关,除非您根据它们减慢程序的速度。超时的函数会花费更长的时间,sleep_until 会花费更长的时间,但不等待未来某个时间点的操作只会显得更快。

// appears to run a million times faster than normal according to (finish-start)
auto start = slow_clock<steady_clock,1000000>::now();
do_slow_operation();
auto finish = slow_clock<steady_clock,1000000>::now();
于 2012-04-08T08:50:41.043 回答
0

对于这种情况:

MessageQueue::poll( Seconds( 1 ) );

如果您只是让您的 MessageQueue 了解它应该以什么“速度”运行,您可以轻松地使用标准时间类。MessageQueue::setPlaybackSpeed(0.5)如果您想以半速运行,只需调用类似的东西,然后让队列从那时起在有人给它一定时间时使用该因素。

至于这个:

sleep( Minutes( 2 ) );

你的旧代码在做什么?我猜想创建的任何对象 Minutes() 都有一个隐式转换运算符到返回秒数的 int?这对我来说似乎太神奇了——最好在 MessageQueue 或其他类上创建一个 sleep() 方法,然后你可以使用与上面相同的解决方案。

于 2012-04-07T23:56:05.923 回答