メインコンテンツまでスキップ

スレッディングモデル

アクティブな Run は、フレームワークとランタイムのスレッド上で処理を実行します。アプリケーションはこれらのスレッドを管理する必要はありませんが、独自のプッシュ、プル、コールバック、およびシャットダウンコードを適切に管理する必要があります。

スレッドの概要

一般的な Run の場合:

スレッド役割所有者
GStreamer ストリーミングスレッドソース、変換、シンクのパスを介してバッファを移動します。GStreamer ランタイム
MLA ディスパッチャースレッドMLA 処理を送信し、完了を収集します。Neat ランタイム
EV74 / CVU ディスパッチャースレッドCVU 側のカーネルを送信し、完了をポーリングします。Neat ランタイム
プル側の待機スレッドとバス監視スレッド出力サンプルをパブリックキューに移動し、ランタイムエラーを報告します。Neat ランタイム
アプリケーションスレッドGraph.build(...)Graph.run(...)Run.push(...)Run.pull(...)Run.stop()、またはコールバックを呼び出します。アプリケーション

グラフフラグメント、ソースノード、およびシンクノードは、ランタイム処理を追加できますが、ルールは変わりません。パブリックな Run は、アプリケーションが制御するハンドルです。

アプリケーションコードが実行される場所

ユーザーコードは、次の場所に存在します。

  • 直接 API 呼び出し: build(...)run(...)push(...)try_push(...)pull(...)close_input()stop()、および close() は、それらを呼び出すアプリケーションスレッドで実行されます。
  • ドロップコールバック: RunOptions.on_input_drop は、プッシュパスで実行されます。短く保ち、カウントして戻ります。
  • テンソルコールバック: Graph::set_tensor_callback(...) は、C++ のコールバックスタイルの処理です。コールバックを短く保ちます。時間がかかる処理は、ランタイムパスにバックプレッシャーを与えます。
  • カスタムノードの説明: パブリックノードの構築とグラフの構成は、ビルド時にアプリケーションスレッドで行われます。

コールバックに時間がかかる処理を隠さないでください。コールバックで多くの処理を行う必要がある場合は、サンプルを独自のキューに渡し、戻ります。

ロックルール

GraphRunTensor、および Sample を、APIでそうでないことが明示されていない限り、単一の所有者オブジェクトとして扱います。

サポートされているパターン:

  • 1つのプロデューサースレッドが push(...) または try_push(...) を呼び出します。
  • 1つのコンシューマースレッドが pull(...) を呼び出します。
  • 別のコーディネータースレッドが、シャットダウン中に stop() を呼び出す場合があります。

リスクのあるパターン:

  • 複数のプロデューサースレッドが、ロックなしで同じ Run にプッシュします。
  • 複数のコンシューマースレッドが、明確な所有権ルールなしに同じ出力からプルします。
  • コールバックが同じ Run にコールバックし、さらに処理を待ちます。

複数のプロデューサーが必要な場合は、Run.push(...) を呼び出す前に、アクセスをシリアライズします。複数のコンシューマーが必要な場合は、1つのスレッドが Neat からプルした後、処理を分散します。

シャットダウンとキャンセル

意図に合ったシャットダウンプリミティブを使用します。

意図使用
最後の入力の後、キューに登録された処理を完了するrun.close_input()、次に、出力がなくなるか、PullStatus::Closed が返されるまでプルします。
現在の処理を停止し、待機中の処理を解放するrun.stop()
ランタイムリソースを解放するrun.close() または、Run オブジェクトのスコープを終了させます。

stop() はキャンセル処理の経路です。キャンセル後、処理中のプルはブロック解除され、プッシュは停止する必要があります。処理が終了しようとしているランタイムにプッシュし続けないでください。

スループットスレッドの構成

アプリがプッシュするライブグラフや高スループットグラフの場合、まず2つのアプリケーションスレッドから始めます。

  1. プロデューサースレッドは、入力を読み込み、stream_id / frame_id をスタンプし、選択した OverflowPolicy に従って try_push(...) または push(...) を呼び出します。
  2. コンシューマースレッドは、継続的にプルし、ランタイムによってバックアップされたバッファーが固定される前に、出力を解放またはコピーします。

独自のキューを中心に、同じ Run オブジェクトを中心に、より多くのアプリケーションスレッドを追加します。ホットループを単調にします。単調な処理は高速です。

関連資料