工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial Internet of Things >> 埋め込み

最高のQtステートマシンパフォーマンスを確保する方法

アプリケーション開発にQtを使用し、ステートマシンを使用している場合は、Qtステートマシンフレームワークを使用している可能性があります。したがって、プレーンC ++またはSCXMLを使用してステートマシンを定義します。別のアプローチは、ステートマシン図からC ++コードを生成することです。この記事では、機能、適用性、パフォーマンスを考慮して、これらのアプローチを比較します。

ソフトウェア開発者として、あなたはすでに多かれ少なかれ複雑なswitch-caseステートメントをたくさん実装しているに違いありません。これは少なくとも私には当てはまります。このswitch-caseコーディングの多くは、本質的には多様なステートマシンを実装することに他なりませんでした。選択したプログラミング言語以外に手元に何もない場合、これはステートマシンのプログラミングを開始する最も簡単な方法です。開始は簡単ですが、ステートマシンの複雑さが増すにつれて、このようなコードの保守性はますます低下します。最後に、この方法でステートマシンを手動で実装し続けたくないと確信するでしょう。 (ちなみに、ステートマシンとは何か知っていると思います。)

ステートマシンの実装

ステートマシンを実装するためのさまざまな代替手段があります。特にC ++のようなオブジェクト指向プログラミング言語を使用している場合のより良い方法の1つは、状態パターンを適用することです。このアプローチでは、状態クラスを使用し、多くの場合、遷移クラスも使用します。次に、ステートマシンは、ステートクラスのインスタンスを作成し、遷移クラスのインスタンスを使用してそれらをワイヤリングすることによって定義されます。この場合、フレームワークはコードサイズと実装の労力を削減するのに大いに役立ちます。

Qtステートマシンフレームワークは良い例です。このAPIを使用すると、コンパクトなコードを使用してステートマシンを「構成」できます。ステートマシンの実行セマンティクスの詳細については、フレームワークによってすでに実装されているため、気にする必要はありません。それでもコードを作成する必要があります。ステートマシンがより複雑になり、数十または数百の状態が含まれるようになると、概要を把握するのが非常に難しくなります。絵は千の言葉の価値があり、状態図のよく知られた概念はこの制約を克服するのに役立ちます。 Qt自体は、W3C標準であるState Chart XML(SCXML)のサポートを提供します。手作業でXMLを作成するのは楽しいことではないため、 Qt Creator シンプルなグラフィカルステートチャートエディタも含まれています。

具体的な実装アプローチに関係なく、ステートマシンを編集および理解するには、グラフィカル構文を使用するのが最適です。このようなグラフィカルモデルは、SCXMLなどの言語でテキストで表現できるだけでなく、プレーンC ++のスイッチケースベースのステートマシンや<のインスタンスを設定するC ++コードなど、あらゆる種類のプログラミング言語のソースコードを生成するためにも使用できます。 em> QStateMachine。 このような変換を行うツールを使用すると、ステートマシンコードを手書きする手間を省くことができます。これにより、3つの実装アプローチすべてが同じユーザビリティレベルに引き上げられます。それにもかかわらず、実装はまだ根本的に異なります。この記事では、実行時の動作、特にパフォーマンスの比較について説明します。


UnsplashPhoto by Austris Augusts on Unsplash

競合他社

では、パフォーマンスはどうですか?必要なCPUサイクルに関して、利用可能なアプローチはどのように異なりますか?具体的な数値を取得するために、パフォーマンステストスイートを設定しました。最初の部分では、さまざまな実装戦略を比較します。競合他社は次のとおりです。

  1. SCXMLインタープリター–テストステートマシンはSCXMLを使用して定義され、Qtの QSCXMLStateMachine によって実行されます。 クラス。
  2. 状態パターン–テストステートマシンは QStateMachine を使用して実装されます クラス。
  3. プレーンC ++コード–テストステートマシンは、基本的なスイッチケースベースのアプローチを適用するC ++クラスによって実装されます。

注:これらの例のコードはここにあります。

最初の2つのバリアントは、シグナルやスロットなどのQtの概念の使用、およびQtイベントキューの使用を意味しますが、プレーンなC ++実装はこのインフラストラクチャを必要としません。アプローチをより比較可能にするために、テストスイートにはさらに2つのテストシナリオが含まれています。

これにより、一方ではシグナルとスロットの使用の影響と、 QEvents の使用の影響を比較することができます。 一方、プレーンC ++の実装と比較すると、ステートマシンの実行コードはすべての場合で同一ですが、ラップが異なるだけです。

テストステートマシン

5つの競合他社すべてをテストするために、図1に示すステートマシンを定義しました。基本的なテストシナリオの場合は1。


図1:YAKINDUステートチャートツールで作成されたテストステートマシン。 (出典:著者)

テストステートマシンは、単純なフラットステートマシンです。 6つの状態を定義します A F へ 状態を循環します。 2つの入力イベント e1 および e2 が定義され、状態遷移を交互にトリガーします。状態遷移が発生すると、単純なアクションも実行されます。各遷移アクションは、 x という名前のステートチャート変数に10を追加するだけです。 。状態 F からの移行 A さらに out を上げます(または放出します) イベント o


図2:QtCreatorのSCXMLモデルとしてのテストステートマシン。 (出典:著者)

このステートマシンは、SCXMLの生成をサポートするYAKINDUステートチャートツールを使用して定義されました。このSCXMLはQtプロジェクトに追加でき、QtCreatorで編集できます。あなたが図で見ることができるように。図2に示すように、ステートマシンは図1のものと同じ構造を有する。 1ですが、移行アクションなどの一部の詳細はQtCreatorに表示されません。 YAKINDU Statechart Toolsにはさらにいくつかの利点がありますが、ここでは説明しません。

ここでさらに重要なのは、YAKINDU StatechartToolsがプレーンなswitch-caseベースのC ++ステートマシンクラスも生成できるという事実です。また、シグナルとスロットを使用してQt対応クラスを生成するオプションも提供されるため、これは便利です。このツールを使用すると、 QStateMachine を使用してステートパターンベースのステートマシンを実装するだけで済みました。 手で。そのバリアントに使用できるコードジェネレーターはありませんでした。それでも、単一のステートチャート定義を使用するだけで、パフォーマンステスト用に意味的に同等のステートマシンを取得しながら、実装の労力を大幅に節約することができました。

すべてのテストケースは同じスキームに従います。個々のイベントの処理にかかる平均時間を測定したかったので、各テストは単一の状態ループの100万回の反復をキャプチャしました。各状態ループは、すべての状態にアクセスし、すべての遷移と遷移アクションを処理するために必要なすべてのイベントを実行します。したがって、状態ループは状態 A で開始および終了します。 アクティブであること。これは、テストケースごとに600万 であることを意味します イベントと移行アクションおよび100万アウト 関連する遷移アクションを持つイベントが処理されます。テストはコマンドラインアプリケーションとして実行され、反復の時間を単一のバッチとして記録しました。イベントごとの消費時間は、測定された時間を in の数の合計で割ることで簡単に決定できます。 イベントと out イベント。テストは数回実行され、最も低い値の測定結果が選択されました。

テストは、Core i7クアッドコアCPU2.4GHzを搭載した古い(2014年半ば)MacBookProでデバッグ情報なしで最適化されたコードを使用して実行されました。もちろん、具体的な数値はマシンやオペレーティングシステムによって異なります。ただし、さまざまな実装アプローチを相互に比較したかったので、これは関係ありません。これらの相対的な違いは、さまざまなハードウェアおよびOSプラットフォームで比較できます。

パフォーマンスの数値を見てみましょう

はい–ほとんどの人がプレーンなC ++実装が他の選択肢よりも高速であることを期待していたと思いますが、違いの大きさは本当に驚異的です。


図3:比較した単一イベント処理時間。 (出典:著者)

プレーンC ++を使用した単一イベントの処理には、平均7ナノ秒かかりました。 SCXMLの使用には33,850ナノ秒が必要でした。これは、約4800の係数であり、大きな違いです。比較のために、SCXMLステートマシンが単一の遷移のみを処理するのに対し、光は10 km以上移動しますが、プレーンC ++ステートマシンでの同じ遷移は、光が2メートルをわずかに超える時間しか残しません。これは、CPUサイクルとエネルギー消費の桁違いが非常に異なることを意味します。

もちろん、具体的な数値は、使用したマシンとテスト手順によって異なります。このトピックについては後で説明します。ただし、最初に他の数値について説明しましょう。最初の3つのテストシナリオにはすべて、YAKINDUステートチャートツールによって生成された同一の状態遷移ロジックが含まれていますが、それぞれが異なる方法でラップされています。

イベントを処理するための信号とスロットの使用は、直接接続を使用する場合、平均で72nsかかりました。したがって、このメカニズムは、実際のステートマシンロジックと比較して、最大90%のオーバーヘッドを課します。現時点では、信号とスロットを使用するとアプリケーションの速度が低下することを主張したくありません。代わりに、ステートマシンのプレーンコードの実装は非常に高速であると主張したいと思います。 。

これを3番目のシナリオと比較すると、イベントキューを使用することによって発生するパフォーマンスオーバーヘッドの印象がよくなります。このシナリオでは、すべてのステートチャートイベントがイベントキューを介してルーティングされます。イベントあたり731nsの場合、シグナルとスロットと比較して約10倍、プレーンC ++と比較して約100倍かかります。

他の2つのシナリオ「plain QStateMachine 」にも、同等のオーバーヘッドが適用されると想定できます。 」と「SCXMLステートマシン」–どちらもアクティブなイベントキューが必要です。したがって、想定されるイベントキューのオーバーヘッドをイベントあたり5200nsから差し引くと、 QStateMachine の大まかな時間消費が得られます。 イベントあたり4500nsのフレームワーク。プレーンコードアプローチと比較して、 QStateMachineベースのステートマシンの実装は低速です。 これは、プレーンなC ++コードの実装と比較して約635倍です。

最後に、SCXMLインタープリターを見てみましょう。これにはJavaScriptコードの解釈が含まれ、約7の別の要素が追加されます。プレーンコードアプローチと比較して、 SCXMLベースのステートマシンの実装は非常に低速です。

階層型および直交型のステートマシンはどうですか?

これまでのところ、単純なフラットステートマシンのプロファイルを作成しました。しかし、ステートチャートははるかに多くの機能を提供し、2つの最も重要な構造的機能は階層と直交性です。では、これらの機能の使用は、ステートマシンのランタイムに関してどのような影響がありますか?

まず、階層の影響を測定するために、プロファイルするステートマシンの階層バリアントを定義しました(図1を参照)。 4.


図4:階層テストのステートチャート。 (出典:著者)

フラットステートマシンとまったく同じ動作を提供しますが、いくつかの複合状態が追加されます。機能を同一に保ちながら、構造を変更するだけで、構造バリアントが意味するオーバーヘッドがあればそれを見つけることができます。

次に、直交性の影響を測定するために、4つの直交領域の形式でフラットステートマシンを複製しました。それらはすべてまったく同じ機能を持っています。したがって、結果のステートマシン(図5を参照)は、単純なステートマシンの4倍の作業を実行します。


図5:直交テストのステートチャート。 (出典:著者)

プロファイリングには、プレーンなC ++とSCXMLの実装を選択しました。これは、これらが最も高速で最も低速なバリアントであるためです。図の図。結果を図6に示します。ステートチャートで階層を使用しても、両方の実装バリアントで測定可能なパフォーマンスへの影響がないことは非常に心強いことです。


図6:階層と直交性のパフォーマンスへの影響。 (出典:著者)

もう1つの肯定的な結果は、直交性を使用しても悪影響がないことです。それどころか、4倍の作業を達成するために少なくとも4倍の処理時間を期待したかもしれませんが、約2.4および約3.1の係数での実行時間の効果的な増加は、4よりも大幅に小さくなります。

なぜそうなのですか?この理由は、個々の状態やイベントの処理から独立したステートマシン処理の一般的な部分があるためです。この部分は、プレーンC ++ステートマシンでは52%(またはイベントあたり3.5ns)かかりますが、SCXMLでは28%(またはイベントあたり9300ns)かかります。最後に、直交状態は、SCXMLと比較して生成されたC ++コードを使用する場合の影響が少なくなります。

結論

プレーンC ++は、他のすべての方法よりもはるかに効率的です。シグナルとスロットまたはQtイベントキューの使用は、複雑なステートマシンアプリケーションの実装と保守を容易にするフレームワークメカニズムです。 Qtステートマシンフレームワークには、これらのメカニズムの両方が必要です。生成されたC ++コードを使用して、選択できます。

多くのシナリオ、特にインタラクティブなシナリオでは、SCXMLステートマシンでさえ十分に高速であり、実行時にステートチャート定義を切り替えることで動作を構成可能にすることで、柔軟性を高めることができます。


埋め込み

  1. 最高のジュエリーデザインCADソフトウェアを選択する方法
  2. 最高のCNCブランド
  3. 適切なCNCマシンを選ぶ方法
  4. 倉庫で緊急時の準備を確実にする方法
  5. 技術スタッフのパフォーマンスを監視する方法は?
  6. 最高の風力タービンブレーキを選ぶ方法
  7. 適切なカートンマシンの選び方
  8. 適切なウォータージェット切断機の選び方
  9. 最高の板金折り機の選び方
  10. 最適な水中ポンプの選び方
  11. 最高のベンダー:エレクトリック・チューブ・ベンダー