iOS/Macで提供しているタイマー精度のことはじめ

Mac OS XやiOSのフレームワークで提供しているタイマーには幾つかの種類がありますが、それぞれの精度の違いはどれくらいあるのだろう、という点が気になって調査していました。 そんな折、「3秒だけCFRunLoopのソースを読んだんだけど」と splhack 氏が色々とアドバイスをくれました。 ちなみに、タイマー調査のためのアプリは、以下の場所で現在作成中です。 続きを読む
17
Hirohito Kato ⌘ @hkato193

Mac OS X上だとNSTimer scheduledTimerWithTimeIntervalの精度がやけに良い。何と±0.1msec。ちなみに別スレッドでnanosleepだと2msくらい。どういうこと?あ、iOSは未確認です。

2010-11-04 19:48:13
Hirohito Kato ⌘ @hkato193

NSThreadのプライオリティを標準の0.5から1.0にしてもnanosleep()は改善せず。NSTimerスゲーっ。計測にはmach_absolute_time()を使ってますよ。

2010-11-04 19:51:18
Hirohito Kato ⌘ @hkato193

GCDのDispatch Sourceを使ったタイマーの場合は0.2msec程度の誤差。うーんうーん、一番悪いと思っていたNSTimerが一番精度が良かった…。

2010-11-04 20:12:58
Hirohito Kato ⌘ @hkato193

iOSだと違う結果になるのかな。

2010-11-04 20:13:36
sakamoto.kazuki @splhack

@hkato193 Queueはどれでしょうか? というかタイマーなんてずれてなんぼだと思いますけども。realtime osじゃないわけですし。

2010-11-04 20:28:05
sakamoto.kazuki @splhack

NSTimerはCFRunLoop内でMachのtimer使ってtimeout待ち、そのあとすぐselector実行。Dispatch SourceのTIMERは、keventチェックするthreadがkevent使ってtimeout待ち

2010-11-04 22:07:49
sakamoto.kazuki @splhack

そのあと指定のDispatch QueueにBlock追加。Global Queue、Serial Queueはその次のコンテキストスイッチあたりで起動、Main QueueはRunLoop回らないと回ってこない。

2010-11-04 22:09:11
sakamoto.kazuki @splhack

keventというかBSDのsystem callもMachにのってると思うので精度はどっこいでしょうから、Dispatch SourceのTIMERからのBlock起動が遅いのはpthread 2つ以上コンテキストスイッチしないといけないため。

2010-11-04 22:13:34
sakamoto.kazuki @splhack

あ、3秒くらいCFRunLoop.c眺めた結果なので鵜呑みにしないように

2010-11-04 22:17:23
Hirohito Kato ⌘ @hkato193

@splhack 3秒でそんなに!NSTimerの無負荷テストの結果がやたら良いのにビビりましたので、NSTimerのスケジュールを別のランループでできないかなあと、まだレファレンスを見てないですが考え中です。

2010-11-05 09:25:14
Hirohito Kato ⌘ @hkato193

メモ1/4 RT @splhack: NSTimerはCFRunLoop内でMachのtimer使ってtimeout待ち、そのあとすぐselector実行。Dispatch SourceのTIMERは、keventチェックするthreadがkevent使ってtimeout待ち

2010-11-05 09:25:45
Hirohito Kato ⌘ @hkato193

メモ 2/4 RT @splhack: そのあと指定のDispatch QueueにBlock追加。Global Queue、Serial Queueはその次のコンテキストスイッチあたりで起動、Main QueueはRunLoop回らないと回ってこない。

2010-11-05 09:25:58
Hirohito Kato ⌘ @hkato193

メモ 3/4RT @splhack: keventというかBSDのsystem callもMachにのってると思うので精度はどっこいでしょうからDispatch SourceのTIMERからのBlock起動が遅いのはpthread 2つ以上コンテキストスイッチしないといけないため

2010-11-05 09:26:29
sakamoto.kazuki @splhack

@hkato193 別のRunLoopでやるということは、そのタイマーによる発呼でthread間通信を行うということになりそうですので、ほとんどDispatch SourceのTimerと同じことになるんじゃないかと予想します。

2010-11-05 09:27:16
sakamoto.kazuki @splhack

誰か メモ 4/4 て書かれたメモを知りませんか

2010-11-05 09:29:19
Hirohito Kato ⌘ @hkato193

メモ 4/4 RT @splhack: @hkato193 別のRunLoopでやるということは、そのタイマーによる発呼でthread間通信を行うということになりそうですので、ほとんどDispatch SourceのTimerと同じことになるんじゃないかと予想します。

2010-11-05 09:30:07
sakamoto.kazuki @splhack

@hkato193 replyすることを見越してメモの総ページ数を決めていた!?

2010-11-05 09:31:18
Hirohito Kato ⌘ @hkato193

@TeamMOSA2 大丈夫です。私もpthreadを自分のアプリで使ってますw。ただ、色んなタイマーを比較しておきたいなあと。 http://bit.ly/bToyYl

2010-11-05 09:34:32
sakamoto.kazuki @splhack

iOSで指定時間待つ方法 pthread_cond_timedwait, pthread_cond_timedwait_relative_np, select, kevent, nanosleep, dispatch_after, dispatch_source+TIMER

2010-11-05 09:35:38
sakamoto.kazuki @splhack

移植性が高い、キャンセルできる、という点で pthread_cond_timedwait に分がありそう

2010-11-05 09:37:14
Hirohito Kato ⌘ @hkato193

@splhack sleepが抜けてます!あとビジーループも。

2010-11-05 09:37:43
sakamoto.kazuki @splhack

@hkato193 usleep,sleepはnanosleep使ってるのでパス。CPU離さないので本当に最後の手段です。

2010-11-05 09:38:52
sakamoto.kazuki @splhack

NSTimerはCFRunLoopTimerとtoll-free bridgedなのでCFRunLoop.cを読みましょう http://bit.ly/cTq3ts

2010-11-05 09:40:31
Hirohito Kato ⌘ @hkato193

@splhack sleep系って、ある程度のしきい値でビジーループかそうでないかを決めていたような。今Source Browserで探してますが(見つかっていない)

2010-11-05 09:40:40
sakamoto.kazuki @splhack

Advanced Synchronization in Mac OS X: Extending Unix to SMP and Real-Time http://bit.ly/ayYIUp

2010-11-05 10:07:14