RTOSのキューの置換


12

タスク間通信またはRTOSの2つのタスク間でデータを共有するために、キューを使用します。しかし、キューの問題は、処理が遅いことです。...バッファ内のデータをコピーし、次にミューテックス処理を行い、次にデータ転送を行います。大きなデータを転送する必要がある場合、イライラするほど遅くなります。別の問題は、複数のタスクが同じキューにアクセスする場合です。次に、画像は次のようになります。-最初にキューへのアクセスを待機してから、内部ミューテックス処理をキューに入れ、データ転送を行います。

これにより、システムのオーバーヘッドが増加します。キューの効率的な代替品は何ですか?

(この質問は、使用しているRTOSに依存しないと思います。ほとんどのRTOSは、この方法でのみキューを処理します)


複数のタスクがアクセスするキューとはどういう意味ですか?キューへの投稿またはキューからの読み取りを意味しますか?複数のタスクは、最小限のオーバーヘッドでキューに投稿できる必要があります。RTOSは、ポストがアトミック操作になるようにミューテックスを処理する必要があります。タスクの99%には、キューに保留してメッセージを処理するループが必要です。キューは(通常)1つのタスクによってのみ読み取られる必要があります。おそらく、設計を見て、キューを置き換えるのではなく、キューをどのように使用しているかを調べる必要があります。
エリック

@エリック:ごめんなさい!私はあなたが言及したメカニズムを使用しています。間違いを指摘してくれてありがとう!私のコードでキューへのアクセスを待っています!
スワナンド

回答:


7

キューは、タスク間通信のスレッドセーフなトランザクションモデルであるため、そのように動作します。厳密性の低いスキームでは、データの破損や所有権の問題が発生します。

データをメモリ内のバッファにコピーしてから、キュー要素にポインターを渡すのですか、それともキュー要素内のすべてのデータを渡そうとしているのですか?ポインターを渡さない場合は、キュー要素を一度に1バイトずつ渡す代わりに、ポインターを渡すとパフォーマンスが向上します。


2
私は同じことを言うつもりでした。キューのデータにポインタを渡すだけで速度を上げることができますが、データを使用して変更しようとするスレッドが2つにならないようにしてください。
-Kortuk

@Kortukが言ったように、「データを使用して変更しようとするスレッドが2つにならないようにする必要があります」...これはオーバーヘッドの増加を意味します...あまり処理を望まない!:(
スワナンド

だから、キューの代わりにNoがあります...データキューの代わりに、ポインタキューを使用する必要があります!
スワナンド

1
@Swanandキューが一方向のみであるようにアプリケーションを計画し(つまり、2つのタスクで同じキューを読み取らない)、ポインターに保存されたデータをすぐに処理してから解放すると、データの共有に問題はないはずです。データを確実にやり取りするために複数のキューを作成する必要があるため、オーバーヘッドが増加しますが、これはマルチタスク環境でビジネスを行うためのコストです。
AngryEE

7

1つの簡単な方法は、キューにデータへのポインターを置き、ポインターを使用してデータを消費することです。

次のことを確認する必要があるため、パフォーマンスと安全性の両方を犠牲にしていることに注意してください。

  1. バッファは、コンシューマがデータを消費するまで有効のままです
  2. 誰かがバッファの割り当てを解除します

動的に割り当てられたメモリを使用していない場合、メモリの割り当てを解除する必要はありませんが、データが消費される前にメモリ領域が再利用されないようにする必要があります。


6

ロックフリーキューは、単一生産者/単一消費者の場合に実装でき、多くの場合、ソフトウェアを設計して、複数生産者または複数消費者のキューの数を最小限に抑えることができます。

ロックフリーキューは次のように構築できます。通信する要素の配列と2つの整数を割り当て、それらをHeadおよびTailと呼びます。Headは、次の項目が追加される配列へのインデックスです。末尾は、次の項目を削除できる配列へのインデックスです。プロデューサータスクはHとTを読み取り、アイテムを追加する余地があるかどうかを判断します。Hインデックスにアイテムを書き込み、Hを更新します。コンシューマタスクはHとTを読み取り、利用可能なデータがあるかどうかを判断し、インデックスTからデータを読み取り、Tを更新します。操作の順序(挿入、更新H、削除、更新T)により、データ破損が発生しないようにします。

複数のプロデューサーと単一のコンシューマー、または単一のプロデューサーと複数のコンシューマーが存在する場合、事実上何らかのリソース制限があり、パフォーマンスリミッターはより多くの可能性があるため、同期を使用する以外には何もありませんロックメカニズムを使用したOSオーバーヘッドよりも、単独のプロデューサ/コンシューマになります。

しかし、複数のプロデューサーとコンシューマーがある場合は、より調整されたコミュニケーションメカニズムを取得できないかどうかを確認するために(デザインスペースで)時間を費やす価値があります。このような場合、単一のキューを介してすべてをシリアル化すると、キューの効率がパフォーマンスの中心的な決定要因になります。


1
私はこれを+1しようとしていましたが、あなたは間違っています:ロックフリーキューは複数のリーダーとライターのために実装することが可能で、それらはより複雑です。(ロックフリーキューgoogle.com/search?q=michael%20scott%20queueに関するMichael + Scottの論文をご覧ください
ジェイソンS

1
@Jason S-Scott論文は、ロックフリーの挿入および削除操作の再入可能性を具体的に主張していますか?もしそうなら、それを抽出して投稿できるなら、してください、それは多くの人にとってかけがえのない資産になるでしょう。読者は、引用された論文が特別な機械命令を使用していることに注意すべきです。一方、上記の投稿における私の立場は、そのような命令を仮定していませんでした。
ジャストジェフ

1
ええ、ロックフリーアルゴリズムのコストは通常​​、CASまたは同等の命令に依存しています。しかし、ここで再入可能性はどのように作用しますか?ミューテックス+ロック構造には意味がありますが、データ構造操作には意味がありません。
ジェイソンS

2

キュー自体が、ロードストア専用、比較交換、または同様のプリミティブで動作するのに十分小さいアイテムを保持している場合、ロックフリーのマルチプロデューサーシングルコンシューマキューで効率的な操作を得ることができ、空のキュースロットの予約値または予約値。キューに書き込むとき、ライターはデータを次の空のスロットに保存するために比較交換を行います。それが失敗した場合、ライターは次のスロットを試します。キューは次の空のスロットへのポインターを維持しますが、ポインター値は「助言」です。システムがload-store-exclusiveではなくcompare-exchangeを使用する場合、異なる「空のスロット」値の「ファミリー」が必要になる場合があることに注意してください。それ以外の場合、ライターが空のキュースロットを見つけて書き込みを試みると、別のライターがスロットを書き込み、リーダーがそれを読み取ります。最初のライターは、知らないうちにデータをリーダーが見えない場所に置きます。この問題は、load-store-exclusiveを使用するシステムでは発生しません。これは、store-exclusiveが古い値に書き戻されたにもかかわらず、データが書き込まれたことを検出するためです。


1

キューの先頭に書き込むことで、キューにもっと効率的にアクセスできます。通常、RTOSのほとんどは、ミューテックスの取得を必要としないキューの先頭への追加をサポートしています。ただし、データをより高速に実行したい場合は、キューの先頭への追加をできるだけ最小限に抑えてください。通常、キュー構造には最大サイズ制限があるため、すべてのデータをキューに入れることができないため、ポインターを渡すのは常に簡単です。

乾杯!!


1

キューは本質的に低速ではありません。それらの実装があります。

盲目的にデータをコピーし、同期キューを使用している場合、パフォーマンスが低下します。

他のポスターが示しているように、ロックフリーの代替手段があります。単一の生産者/単一の消費者の場合は簡単です。複数のプロデューサーとコンシューマーの場合、マイケルとスコットによるロックフリーキューアルゴリズム(姓)は標準であり、JavaのConcurrentLinkedQueueの基礎として使用されます。

特定のケースでキューの必要性を最適化することは可能ですが、タスクを分離できるようにすることで、システムに大幅な簡素化の利点をもたらす並行性の保証を提供します。


Michael&Scottの論文から:「これは、ユニバーサルなアトミックプリミティブを提供するマシンに最適な明確なアルゴリズムです(たとえば、比較/スワップ、またはリンク/ストア条件付きロード)。これは実際にはスレッドを正確にロックするわけではありませんが、ここで同期の形式があります。
ジャストジェフ

あなたにはポイントがあります。メモリバリアへの排他的アクセスからの同時実行の要件を減らすことができます。
ジェイソンS
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.