開発後半になってタスク切り替えのタイミングやマルチタスクのIO/メモリアクセスの問題で苦労した開発者の方も多いのではないでしょうか。これらの問題は発生頻度が低く原因の特定に時間を要するという厄介な面があり、結果的に予定外の工数を大幅に費やしてしまいがちです。
また、ソフトウェアの規模が大きく複雑である昨今の組込み機器ではタスク切り替え関連の問題も増える傾向にあり、Task Timing Analysisの必要性も高まってきています。そこで今回はTask Timing Analysisの手法や、弊社の動的テストツールDT10を使った工数増加を抑えるための解析方法を紹介します。
CONTENTS
Task Timing Analysisとは
Task Timing Analysisは、マルチタスクで動いているソフトウェアに対して各タスクの動きを分析して設計した通りにソフトウェアが動作しているかを検証する方法です。タスク切り替えのタイミング、CPU負荷率、タスク内部での関数実行時間、タスクが使用するIOやメモリ管理など様々な観点からソフトウェアの動きを分析してソフトウェアが要求仕様を満たしているかを検証します。
Task Timing Analysisの重要性
昨今のソフトウェア開発はコードの再利用・分散開発・OSSの利用など開発の効率を上げるために様々な工夫をしていますが、その結果、自分が担当しているモジュール以外の動作についてはすぐに把握することが難しい状況になっています。このような環境では各モジュール間のタイミングや優先順位などを考慮していないケースが多く、統合テストの段階になって問題が頻発する傾向があります。そのようなケースでは解析や修正、設計の見直しなど、大幅な手戻りが必要とされる場合もあります。
Task Timing Analysisを行うことで、問題発生時に原因の特定にかかる工数を減らすことができます。さらに結果を次のプロジェクトで利用することで事前に問題の発生を防ぐこともできます。ではどのようにTask Timing Analysisを行うのでしょうか。
Task Timing Analysisの方法
一般的にTask Timing Analysisには3つの方法があります。以下の図のように設計フェーズで行う方法とテストフェーズで行う方法に分けられます。
Model-based Analysis
Model-based Analysisは設計書や既存の測定結果に基づき、タスクの動きを予測する方法です。設計書だけではなく既存の測定結果も流用することで予測の正確度を上げられます。手軽に適用できる方法ではありますが結果はあくまでも予測であるため、後述する2つの方法と同時に使う必要があります。分析というより、他の方法を適用する為の準備に近い方法になります。
Simulation-based Analysis
Simulatorを使用して分析をする方法です。後述するMeasurement-based Analysisはソースコードが実装できてターゲットが動かせる状態ではないと適用できませんが、Simulatorを使用するこの方法はソースコードがまだ実装されていない状態でも設計時の情報だけで分析することができます。そのため、設計フェーズから実施することが可能というメリットがあります。タスク切り替えタイミングの問題は設計時のミスで発生する場合が多いですが、この方法はコードを実装する前に問題を把握して修正できるので手戻りの工数を削減することができます。
一方、Simulatorを使用するということはツールの導入が必須ということになりますので、導入のハードルが高いことがデメリットです。なお、導入するツールは少なくとも以下の機能を持っている必要があります。
– スケジューリング最適化
– 問題を解析する為のデバッグ機能
– CPU負荷率分析
Measurement-based Analysis
実際にターゲット機器を動かして測定するMeasurement-based Analysisは一番良く使われる方法です。測定する方法は大きく以下のように分類されます。
– printf/Log Systemを使用
– オシロスコープを使用
– デバッグ/テストツールを使用
測定する方法は様々ですが、共通点としてシンプルな仕組みを持つこと、そして以下のような手順で手軽に測定できることが挙げられます。これはMeasurement-based Analysisのメリットでもあります。
1. ターゲットに測定する為の仕掛けを用意する
2. ターゲットを動かして測定
3. 分析
ただし、Measurement-based Analysisが適用できるのは開発プロセスの後半、つまり実装が終わってテストする段階のため、設計時の深刻なミスが原因の場合は手戻りが発生し、修正に大きな工数が必要となるワーストケースも考えられます。したがって以下のように全ての方法を使用して運用する方法が理想的といえます。
とはいえ必ずしもModel-based AnalysisやSimulation-based Analysisを導入できるとは限らないのが実情だと思います。そのような場合、Measurement-based Analysisをいかに効率よく行うか、という点が予期せぬ工数増大を抑えるためのカギになります。
DT10を使ったTask Timing Analysis
弊社が開発・販売している動的テストツールDT10でもTask Timing Analysisを行うことができます。DT10ではターゲット機器のソースコードに、テストポイント(≒printfデバッグで使用するprint文)をDT10アプリケーションが自動で挿入します。その状態でビルドを行い実際にターゲット機器を動作させることで、「実際の動作」と「実行経路・変数値」などの情報、そして「ソースコード」を照らし合わせて解析できる動的テストツールです。実際にTask Timing Analysisに使える機能を見てみたいと思います。
実行時間レポート
DT10のテストポイントでは、どの処理が実行されたかだけでなく時間情報も付加されています。この時間情報をDT10のアプリケーションが自動で解析することによって、関数ごとの実行時間や周期時間を確認することができます。例えば実行時間は以下のように確認できます。
実行時間レポート(上図上部分)では、関数ごとに最小時間、最大時間、そして平均時間が分かります。例えばこれらを確認し、設計と異なるような場合や平均時間と最大時間の差が大きい場合などは、処理の実行に時間がかかりすぎてタスクの切り替えに影響を与えているのではないか、といった観点で異常箇所を抽出できます。DT10ではそのようにして抽出した異常箇所のログデータも確認することができる(上図下部分)ため、そのときにどのような処理が実行されていたか効率的に確認できます。
これとは別に、OSのタスクディスパッチもしくはタスク切り替え発生時に実行されるソースコードの先頭部分に挿入する、タスク情報を出力する専用のテストポイントもDT10には存在します。このテストポイントを使用することでMeasurement-based Analysisでの分析がさらに詳細に行えます。以降の節では、そのテストポイントを使って出力できる情報を見ていきたいと思います。
関数遷移スコープ
この機能では、上記の専用のテストポイントから取得したタスクの切り替えタイミングと、タスク内部で実行される関数の状況を同時に把握できます。マルチコアにも対応していますので、コアのマイグレーション状況も確認することができます。
プロセス占有率スコープ
同じく上記の専用のテストポイントを使用すると、各タスクの占有率及びCPU占有率を把握することができます。これらの変化をグラフ表示する機能がプロセス占有率スコープです。
分析したいタスクの占有率が予測と違ったり、実動作と比べてあまりにも占有率が大きい(=負荷が高い)といったことが発生しているかどうかを確認することができます。また、そういった箇所は先ほどの実行時間レポートや関数遷移スコープ、そしてログデータと連携して関数内部の状況も把握できますので、問題発生時の原因の特定がしやすくなります。
さて、DT10の機能の一例をご覧いただきましたが、すべてに共通しているのは「タスク切り替え時の情報」と「そのとき実行されている処理」を照らし合わせて確認できるという点です。また、これらの情報は次のプロジェクトの設計段階で活かすことができ、結果的に効率化に寄与します。こういった積み重ねによって、開発手法をひとつ上のレベルに押し上げることもできるのではないでしょうか。
まとめ
Task Timing Analysisにはいくつかの方法がありますが、起こり得ることに対してどのように対策するか、どのように問題の芽を摘むかという考え方が重要なのはどの方法にも共通して言えることです。そして、どれがベストかということではなく、開発プロセス、開発期間、リソース、ツール、開発規模など考慮しなければいけない要素と照らし合わせ、その環境に合う方法を検討することがベストだと思います。