-1

何をtime(NULL)返しますか?ドキュメントを考えると、次のコードを実行すると、エポックからの秒数が返されると想定していました。

#include <iostream>
#include "Time.h"
#include "Math.h"

int main () {

    double curT = 0;
    double curJ = 0;

    time_t curTtimeT = 0;
    double curJtimeT = 0;

    //run indefinitely... use a debugger you can stop :-)
    for (double j = 0; j < 2000000000; j++) {

        //get the current time
        curT = time(NULL);
        curTtimeT = time(NULL);

        //check if current time equals previous time
        if (time(NULL) != curT) {
            //output time and approx. "time" through iteration
            std::cout << "Time match with doubles:\t" << curT << "\tdeltaJ:\t\t\t" << (j - curJ) <<std::endl;
            curT = time(NULL);
            curJ = j;
        }

        if (time(NULL) != curTtimeT) {
            //output time and approx. "time" through iteration
            std::cout << "Time match with time_t:\t\t" << curTtimeT << "\t\tdeltaJtimeT:\t\t" << (j - curJtimeT) <<std::endl;
            curTtimeT = time(NULL);
            curJtimeT = j;
        }

    }
    return 0;
}

次の結果が得られます (実行間でスキップにパターンがあるようには見えません)。

Time match with time_t:     1348873002      deltaJtimeT:        290842
Time match with doubles:    1.34887e+09 deltaJ:         2.41017e+06
Time match with doubles:    1.34887e+09 deltaJ:         1.08409e+06
Time match with doubles:    1.34887e+09 deltaJ:         2.16587e+06
Time match with time_t:     1348873007      deltaJtimeT:        5.36928e+06
Time match with doubles:    1.34887e+09 deltaJ:         1.08696e+06
Time match with time_t:     1348873008      deltaJtimeT:        1.08696e+06
Time match with doubles:    1.34887e+09 deltaJ:         1.08534e+06
Time match with doubles:    1.34887e+09 deltaJ:         3.18296e+06
...
Time match with time_t:     1348873122      deltaJtimeT:        2.16217e+06
Time match with doubles:    1.34887e+09 deltaJ:         6.42553e+06
Time match with doubles:    1.34887e+09 deltaJ:         1.08727e+06
Time match with doubles:    1.34887e+09 deltaJ:         2.14147e+06
Time match with doubles:    1.34887e+09 deltaJ:         1.04733e+06
Time match with time_t:     1348873130      deltaJtimeT:        8.42965e+06

注: このdeltaJ出力を使用して、コンソールが実際にこのループから結果を出力するタイミングに関して、明確な視覚的な違いをもう少し数値的に示しています。

double明らかに、これはエポックからの秒数を一貫して返しているようには見えません。代わりに、1 秒あたりの両方で1 行に非常に近い非常に一貫した出力を確認できるからtime_tです。1348873002代わりに、との間の範囲全体を見逃しています1348873007- これらの値はどれも 経由で見つからないようtime(NULL)です。これらのギャップは、このループのランタイム全体を通して一貫して表示されます。

さらに、数秒間出力されないこともあります (1348873122との間のギャップを参照してください1348873130)。

リアルタイムの 1 秒ごとに、出力に両方の変数タイプの 1 つのエントリが表示されない理由がわかりません。代わりに、time(NULL)エポックからの秒数を一貫して返しないようで、実際にはいくつかの値をスキップします。

私は何が欠けていますか?

Snow Leopard 上の X-Code 3.2.5 の 2.4GHz デュアルコア Macbook Pro でこれらのテストを実行しています (おそらく、この問題は私のシステムに固有のものです)?

4

5 に答える 5

1

<time.h>またはを参照してくださいtime()

time_t time(time_t *res);

の型time_tは通常、符号付き整数型です。

を使用しているため、全体"Time.h"の定義が異なる場合があります。time()

私はきれいに整列され、フォーマットされた出力を取得することを好み<cstdio>ます (私は C++ プログラマーよりも C プログラマーです) が、コードを次のようにコンパイルすることができます。

#include <ctime>
#include <cstdio>
using namespace std;

int main()
{
    double curT = 0;
    double curJ = 0;

    time_t curTtimeT = 0;
    double curJtimeT = 0;

    //run indefinitely... use a debugger you can stop :-)
    for (double j = 0; j < 2000000000; j++)
    { 
        //get the current time
        curT = time(NULL);
        curTtimeT = time(NULL);

        //check if current time equals previous time
        if (time(NULL) != curT) {
            printf("CurT:      %16.2f;  deltaJ: %16.2f\n", curT, j - curJ);
            curT = time(NULL);
            curJ = j;
        }

        if (time(NULL) != curTtimeT) {
            printf("CurTtimeT: %13lld;     deltaJ: %13lld\n", (long long)curTtimeT, (long long)(j - curJtimeT));
            curTtimeT = time(NULL);
            curJtimeT = j;
        }
    }
    return 0;
}

次のような出力が生成されます。

CurT:         1348875805.00;  deltaJ:       1215329.00
CurT:         1348875806.00;  deltaJ:       1403669.00
CurTtimeT:    1348875806;     deltaJ:       2618998
CurTtimeT:    1348875807;     deltaJ:       1395183
CurT:         1348875808.00;  deltaJ:       2815155.00
CurT:         1348875809.00;  deltaJ:       1401716.00
CurTtimeT:    1348875809;     deltaJ:       2821688
CurT:         1348875810.00;  deltaJ:       1410729.00
CurT:         1348875811.00;  deltaJ:       1411382.00
CurTtimeT:    1348875811;     deltaJ:       2822111
CurTtimeT:    1348875812;     deltaJ:       1420231
CurT:         1348875813.00;  deltaJ:       2840762.00
CurTtimeT:    1348875815;     deltaJ:       4242399
CurT:         1348875816.00;  deltaJ:       4231937.00

Cur*値は理にかなっています。deltaJループカウンターと時間値の違いを行うため、値は無関係です。何を期待しているかわかりません。

(MacBook Pro、2.3 GHz Intel Core i7、Mac OS X Lion 10.7.5、GCC 4.6.0 — 今週初めの災害の後、GCC の新しいバージョンを回復する必要があります。)

于 2012-09-28T23:23:25.560 に答える
1

double明らかに、これはエポックからの秒数を一貫して返しているようには見えません。代わりに、1 秒あたりの両方で1 行に非常に近い、非常に一貫した出力を確認できますtime_t

これは従いません。コードが実際とは少し異なるものになることを意図していたと思います。

具体的には、これを変更する必要があると思います:

    //run indefinitely... use a debugger you can stop :-)
    for (double j = 0; j < 2000000000; j++) {

        //get the current time
        curT = time(NULL);
        curTtimeT = time(NULL);

これに:

    //get the current time
    curT = time(NULL);
    curTtimeT = time(NULL);

    //run indefinitely... use a debugger you can stop :-)
    for (double j = 0; j < 2000000000; j++) {

そのままでは、一種の競合状態があるためです。ループの特定の部分timeで戻り値が変化するかどうかをテストしています。明らかに、100% の確率で起こるわけではありません。ループのある部分で 2 番目がロールオーバーすることもあれば、別の部分でロールオーバーすることもあります。

于 2012-09-28T23:25:31.230 に答える
1

テスト コードが少し複雑になりすぎたと思います。最初の列は正しいように見えますが、すべての桁が表示されていないため、秒数がカウントアップされていません。そして、 time_t と double を使用すると、出力が混乱するだけです。これを試してみてください。かなり面倒ですが、毎秒新しい時刻が表示されます。

#include <iostream>
#include "Time.h"

int main () {
    //get the current time
    time_t currtime = time(NULL);

    //run indefinitely... use a debugger you can stop :-)
    for (double j = 0; j < 2000000000; j++) {

        //wait until a second has passed
        while (time(NULL) < currtime + 1) {
        };
        currtime = time(NULL);
        std::cout << "Time: " << currtime << "\n";
    }
    return 0;
}
于 2012-09-28T23:36:18.730 に答える
0

ここでは、アプリケーションが干渉なしで実行されると仮定します。システムはプリエンプティブ システムであるため、OS がプロセスと交差して別の処理を行う場合があります。「タイム リープ」はそれが原因である可能性があります (たとえ私がプロセスを5秒間放棄するかどうかはまだ興味がありますが、それでも発生する可能性があります)...

また、予期せずに最適化が行われたために、コードの動作が異なる可能性があると思います。コンパイラの設定を確認し、最適化を無効にして、違いがあるかどうかを確認することをお勧めします...

システムを考慮して、これはほとんどありそうにありませんが、オーバーフローもチェックしてみてください(ここで行うことには64ビット整数で十分なはずです)...

于 2012-09-28T23:25:35.553 に答える
0

代わりに、1 秒あたりの double と time_t の両方で 1 行に非常に近い非常に一貫した出力を確認できます。

それはまさにあなたが見ることを期待してはならないものです. 多くの明らかなランダム性が見られることを期待する必要があり、それはまさにあなたが見ているものです. ループの各反復で 2 ~ 6 回の呼び出しが行われtime()、フォーマットされた出力が生成される場合と生成されない場合があります。I/O は高価で、フォーマットされた I/O は非常に高価で、time()次のようなシステム コールも高価です。

コンピューターは、アプリケーションの実行以外にも多くのことを行っています。画面に表示する必要があるコンテンツを作成している、コンピューターを更新する必要があるかどうかを確認している、ウイルス対策プログラムを実行している、ユーザーが閉じていないブラウザー ページを更新している、などです。CPU は常にコンテキストを切り替えています。プログラムを実行してから、無数の他のアクティブなプログラムを実行するまでの間。これらのシステム コールは、コンテキストを切り替えるのに最適な場所 (および推奨される場所) です。

ループの各反復内には、プログラムが OS スイッチ コンテキストを招待する場所が 8 つあります。多くのバリエーションが見られることはまったく驚くべきことではありません。

于 2012-09-28T23:35:23.190 に答える