0

(自家製の) 既存の時間クラスから C++11 の新しい時間機能を使用するように既存のプログラムを移行しようとしています。リアルタイム処理の場合、C++11 の機能を自家製の時間クラスにマップする方法は明らかです。C++11 のクロノタイム機能を使用して非リアルタイム モードをサポートする方法はあまり明確ではありません (たとえば、「バッチ モードでできるだけ速く実行する」、「4 分の 1 の速度で実行するデモ モードで実行する」など)。 .) 自家製のクラスがサポートしています。clockこれは、壁時間を「再生」速度に適切にマッピングする特別な s を定義することによって達成されますか? どんな助けでも感謝し、例は素晴らしいでしょう。

たとえば、移行するコードには次のような構造があります。

MessageQueue::poll( Seconds( 1 ) );

また

sleep( Minutes( 2 ) );

Secondsまたはオブジェクトは、Minutesプログラムが実行されている速度を認識して、乗数または変換関数をあらゆる場所で使用する必要がないようにします

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

また

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

私が期待していたのは、 とstd::chrono::durationcustomstd::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 に答える