0

私は毎秒 20 回更新するエンジンを搭載したゲームに取り組んできました。ここで、パフォーマンスの数値を取得し、レンダリングとロジックの更新を微調整する必要があるところを指摘する必要があります。そうするために、次のように実装されたタイミングコードをゲームループに追加し始めました...

NSDate* startTime = [NSDate date];
// Game update logic here....
// Also timing of smaller internal events
NSDate* endTime = [NSDate date];
[endTime timeIntervalSinceDate:startTime];

ただし、外側のタイミング ロジック内でブロックの時間を測定すると、ブロックの実行にかかった時間が、全体の所要時間と一致しないことに気付きました。

そこで、テストを完了するのにかかった全体の時間を計測してから、10 個の小さなイベントを計測するという問題を実証するために、小さな単体テストを作成しました。

- (void)testThatSumOfTimingsMatchesOverallTiming {

NSDate* startOfOverallTime = [NSDate date];

// Variable to hold summation of smaller timing events in the upcoming loop...
float sumOfIndividualTimes = 0.0;
NSTimeInterval times[10] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
for (int i = 0; i < 10; i++) {
    NSDate* startOfIndividualTime = [NSDate date];
    // Kill some time...
    sleep(1);
    NSDate* endOfIndividualTime = [NSDate date];
    times[i] = [endOfIndividualTime timeIntervalSinceDate:startOfIndividualTime];
    sumOfIndividualTimes += times[i];
}

NSDate* endOfOverallTime = [NSDate date];
NSTimeInterval overallTimeTaken = [endOfOverallTime timeIntervalSinceDate:startOfOverallTime];

NSLog(@"Sum of individual times: %fms", sumOfIndividualTimes);
NSLog(@"Overall time: %fms", overallTimeTaken);

STAssertFalse(TRUE, @"");
}

そして、ここに出力があります...

Sum of individual times: 10.001377ms
Overall time: 10.016834ms

これは私の問題を非常に明確に示しています。全体の時間は 0.000012 ミリ秒でしたが、小さなイベントには 0.000001 ミリ秒しかかかりませんでした。では、残りの 0.000011ms はどうなったのでしょうか?

私のコードに特に問題があるように見えるものはありますか? または、使用する必要がある別のタイミングメカニズムはありますか?

4

1 に答える 1

1

まあ、実行にはある程度の時間が必要で[NSDate date]あり、[endTime timeIntervalSinceDate:startDate]それがおそらく違いの原因です.

ただし、CACurrentMediaTime()どちらを返すCFTimeIntervalか (これは単なる double です)、またはmach_absolute_time()unsigned long int を返すかを使用します。これらはどちらもオブジェクトの作成を回避し、おそらく時間がかかりません。

もちろん、フレームごとに 2 つの数値を減算することになりますが、これには時間がかかります。それを回避するための私の提案は、単にlastFrameEndを使用することです:

CFTimeInterval lastFrameEnd = CACurrentMediaTime();
while (true) {
  // Game update logic here....
  // Also timing of smaller internal events
  CFTimeInterval frameEnd = CACurrentMediaTime();
  CFTimeInterval duration = frameEnd - lastFrameEnd;  //Use this
  lastFrameEnd = frameEnd;
}

これには、1 つのフレームの終了から次のフレームの終了までにかかる時間が考慮されます。これには、減算とメソッド呼び出しにかかる時間が含まれます。

于 2010-12-25T18:24:43.530 に答える