2013-01-15 5 views
52

クォーツイベントのパフォーマンス問題、具体的にはCGEventPost:GPU負荷が高いときにCGEventPostがブロックする可能性があります。我々はa small benchmark application to demonstrate the issueを作成しました。このアプリケーションは、イベントを作成、投稿、リリースするループです。GPU負荷の下でのCGEventPostの脆弱なパフォーマンス

以下は、アプリケーションの実行結果です。最初の実行はアイドル状態のシステムです。 2回目はFurMark(GPUストレステスト)でダイヤルを可能な限り大きくして実行します。

  • 内部ループは、基本的にはQuartz Eventsでイベントを作成、投稿、解放するだけです。
  • アウターは、私たちのプログラムが目を覚ます(睡眠)の時間です。私たちが眠っている時間に近いはずですが、システムが圧迫されていると遅れることがあります。
  • 投稿は投稿の所要時間です。  

    18:58:01.683 EventPerformance[4946:707] Measurements: (outer should be close to 10) 
    18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.684 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.685 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.26, CGEventPost (ms): 0.03 
    18:58:01.685 EventPerformance[4946:707] inner (ms): 0.06, outer (ms): 10.85, CGEventPost (ms): 0.05 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.07, outer (ms): 10.41, CGEventPost (ms): 0.04 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.04, outer (ms): 10.39, CGEventPost (ms): 0.03 
    18:58:01.686 EventPerformance[4946:707] inner (ms): 0.05, outer (ms): 11.02, CGEventPost (ms): 0.03 
    18:58:01.687 EventPerformance[4946:707] inner (ms): 0.03, outer (ms): 10.67, CGEventPost (ms): 0.03 
    18:58:01.687 EventPerformance[4946:707] inner (ms): 0.08, outer (ms): 10.09, CGEventPost (ms): 0.05 
    18:58:01.688 EventPerformance[4946:707] Averages: (outer should be close to 10) 
    18:58:01.688 EventPerformance[4946:707] avg inner (ms): 0.05, avg outer (ms): 10.64, avg post (ms): 0.03 
    

は、ここではイベントをポストすることは、平均で約0.03ミリ秒を要していることがわかります。また、スレッドは約0.5ms後に目が覚めているようです。 CGEventPostにスパイクはありません。

19:02:02.150 EventPerformance[5241:707] Measurements: (outer should be close to 10) 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.23, CGEventPost (ms): 0.02 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.54, CGEventPost (ms): 0.02 
19:02:02.151 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 11.01, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.74, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.02, outer (ms): 10.20, CGEventPost (ms): 0.01 
19:02:02.152 EventPerformance[5241:707] inner (ms): 10.35, outer (ms): 11.01, CGEventPost (ms): 10.35 
19:02:02.152 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.02, CGEventPost (ms): 0.02 
19:02:02.153 EventPerformance[5241:707] inner (ms): 58.90, outer (ms): 10.11, CGEventPost (ms): 58.90 
19:02:02.153 EventPerformance[5241:707] inner (ms): 0.03, outer (ms): 10.12, CGEventPost (ms): 0.02 
19:02:02.153 EventPerformance[5241:707] Averages: (outer should be close to 10) 
19:02:02.371 EventPerformance[5241:707] avg inner (ms): 7.71, avg outer (ms): 10.44, avg post (ms): 7.71 

システムのGPU負荷が高い場合、イベントを送信すると、マイクロ秒ではなく(スパイク)ミリ秒かかることがあります。極端なGPUストレス(< 1 FPS)では、この値には数秒かかります。 CGEventPost 時々は、GPUが復帰する前にいくつかの作業を完了するのを待っているようです。私たちのスレッドは、まだ目立つ遅延/スパイク(外側)がなく、通常スケジュールされています。

アイデアをいただければ幸いです。

+2

膨大な量のOpenCLを提出すると、Windowsでさらに悪い影響が出ます(私はあなたがOSX上であることを知っています)。すべてのGPU描画がクロールに遅くなります。 GPUには優先順位や波面の長さなどの概念がないようです。 – doug65536

+2

インストゥルメントでプロファイリングを試して、減速の発生場所を確認してください。 – monoxygen

+1

これを実行したコンピュータのグラフィックスカードの種類は?統合、統合+離散、離散?異なるグラフィックスカード構成のシステムで異なる動作を実行するかどうかを確認することは面白いでしょう。 – monoxygen

答えて

5

私はあなたが楽器で「スケジューリング」または「システムコール」機器を使用してこのことを確認することができます

...あなたはキュー(基礎となるマッハポートを)いっぱいにしていると思います。 (空白の新しい文書を作成し、楽器を追加してからFile > Record Options...の下にあることを確認してください) "これは、スレッドのブロック、スリープ状態、起動時、 。

まず、CGEventPostを呼び出すスレッドのスレッド優先度(cf. man 3 PTHREAD_SCHEDPARAM)を上げてみます。スレッドが優先度の低いスレッドでブロックされている場合、カーネルは優先度の逆転を避けるためにブロックスレッドの優先度を一時的に上げ、タスクを早期に完了させる必要があります。

あなたが投稿したいイベントのキューを作成します。

全体的に私はあなたが以下のように、2スレッドソリューションを実装する必要がありますと思います。あなたのメインスレッド(またはイベントポストスレッド)からこのキューにイベントをポストし、次にキューを歩き、未処理のイベントを投稿するために、CGEventPostで2番目のスレッド(作成したイベントコンシューマスレッド)に通知します。

ブロックすると、2番目のイベントポスティングスレッドはブロックされますが、他のスレッドはブロックされません。 CGEventPostが最終的にブロックを解除すると、イベントコンシューマスレッドによって送信された未処理イベントが消費され、イベントコンシューマスレッドは投稿イベントを再開できます。

別の可能性:イベントを連携させることはできますか?特定の種類のイベント(マウスの動き?)があり、より少ないイベントにまとめることができます。あなたはたぶんの待ち行列にたどり着きますが、2スレッドのアプローチがおそらく最善の策だと思います。

+0

私はCGEventPostからIOHIDPostEventに切り替わったので、GPUの負荷の方がはるかに優れていますが、他の状況ではまだブロックしています。 – Dae

+0

Instrumentsを使用すると、IOHIDとQuartzの両方でmach_msg_trapがブロックされている可能性があります。おそらくメッセージの受信を待っています。私たちは詳細を管理することはできませんでした(つまり、誰が相手にいるのですか、なぜブロックしているのですか)。 – Dae

+0

リアルタイム優先度はテストアプリケーションから誤って削除されましたが、実際のプロジェクトではそれを持っています。 (ただし、違いはありません)。コアレーシングとスレッディングを実装しました - 提案に感謝します! – Dae

関連する問題