連載|組込みシステム​における​マルチコア
第4回 ​並列化の​実践と​設計ポイント ​―​マルチ​コア​活用

CPUやGPUのマルチコア化が進み、ソフトウェア開発においても並列処理の最適化は避けて通れないテーマとなりました。

最終回となる第4回では、実際のアプリケーションや組込みシステムでどのように並列化を適用し、性能を最大限に引き出すかを具体的な設計視点から解説します。これまで学んだ概念を「実務」でどう活かすか、その総まとめです。

1. マルチコアシステム開発のデバッガ技術

2000年代から2010年代の前半は、組込みシステムでのマルチコア採用はまだ様子見の状況でした。ある団体がマルチコアの利用調査を行ったところ、「今後は検討したいが以下のような不安がある」とコメントがあったようです。

  1. チップが入手困難
  2. マルチコアアプリケーションをデバッグするとき、従来のように使えるハードウェアデバッガがあるか不安
  3. 設計、実装手法が未確立
  4. 既存アプリケーションとの互換性が不安
  5. バスアーキテクチャなど、ハードウェアが複雑化する

その後、マルチコアSoCの製品バリエーションは増え、流通性も高まっています。従来のプラットホームをリプレースするにあたり、マルチコアのCPUを検討することは必然といえます。

開発方法については、従来のマルチタスク設計・実装の延長で考えれば良いと認識されているようです(もちろん、タスクが真の並列実行することは留意する必要はあります)。

もし、既存システムがグローバル変数でタスク間連携を密に実装していることでマルチコア化に懸念がある場合は、マルチコア化の前にプログラムをモジュール構造にリプレースした方が良いかもしれません。

当時は、使えるデバッガがあるのか不安視する意見もありました。何らかの依存性があるタスクが並列動作すると、そのコアのプログラムはユーザが設定したブレークポイントで実行を停止します。しかし、他コアのプログラムが動作を継続した場合、通常とは異なる形でシステムの状態が進んでしまい、システム全体のデバッグに影響を与えます。
それを解決するために、「クロストリガー」と呼ばれる機能を利用します。クロストリガーは、あるコアがブレークポイントで停止した時、他のコアを停止するようトリガーをかける機能です。クロストリガーによって、デバッグしたいプログラムの一貫性が保証されます。

デバッガのユーザインタフェースにもSMPモード/AMPモードをサポートするものがあり、このようなデバッガを使うとSMP視点/AMP視点でデバッグすることができます。

マルチコアデバッガのSMPモード

マルチコアを、従来のシングルコアをデバッグするインタフェースです。1つのウィドウでシステム全体のデバッグ操作を行うことができます。操作・閲覧コアは、ツールアイコンなどで切り替えます。

マルチコアデバッガのAMPモード

マルチコアをマルチコアのままデバッグするインタフェースです。コアごとに複数のデバッガやデバッグウィドウが立ち上がり、各コアを個別にデバッグ操作させてくれます。

デバッグシステムについては、商用ベンダが提供するものは、ユーザがマルチコアシステムを開発するための受け入れ体制が整えられていると感じます。

2. TOPPERSカーネルのマルチコア拡張の紹介

NPO法人TOPPERSプロジェクトは、μITRON ver4を継承するとともに、ITRONでは仕様策定されなかったマルチコア拡張仕様を定義し、その実装を公開しています。

  • TOPPERS/FMP(新世代カーネル仕様書)
  • TOPPERS/FMP3(第3世代カーネル仕様書)

TOPPERSのマルチコア拡張実装は、メモリ共有を前提とした直接操作方式の実装です。新世代カーネル仕様は従来のティック(1ms)動作実装、第3世代カーネルは高精度システム時刻(1us)とティックレス動作が特徴です。

TOPPERSのマルチコア拡張の実装要件を以下に示します。

(a) 各プロセッサで、プログラムやROMデータに対して同一アドレスでアクセス可能であること。

  • それぞれのプロセッサがアクセスする物理的なメモリが異なっていても、同じ内容を保持していればよい。

(b) 全プロセッサから、同一のアドレスでアクセス可能なRAMがあること。

(c) すべてのプロセッサから、任意のプロセッサに対して割込み(プロセッサ間割込み、IPI)を発生可能であること。

(d) プロセッサ間での排他制御のための機構を持つこと。

例 : test & set(TAS)命令、compare & swap(CAS)命令、 専用Mutex回路

参照:WikiPedeia 不可分操作

(e) プロセッサ間の排他制御機構を用いて、ロックを最低2個作成可能であること。

  • 2個のみの場合はジャイアントロック方式のみサポート可能。
  • プロセッサごとに2個+1個作成可能の場合、プロセッサロック方式をサポート可能。
  • ロックの作成個数に上限がない場合、細粒度ロック方式もサポート可能。

注:第3世代カーネルではジャイアントロック方式のみをサポート。

(f) 各プロセッサがユニークなIDを持ち、ソフトウェアから自プロセッサを判別可能であること。

以下は、TOPPERSのCPUアフィニティのコンフィグレーション例です。プロセッサクラス(CLASS)という概念の元、カーネルオブジェクトをCLASSの囲み内に定義します。これにより動作するCPUコアを指定します。

/* コア1 */
CLASS(TCL_1){
	CRE_TSK(MAIN_TASK1, { TA_ACT, 1, main_task, MAIN_PRIORITY, STACK_SIZE, NULL });
	CRE_TSK(SERVER_TASK1, { TA_ACT, 1, server_task, SERVER_PRIORITY, STACK_SIZE, NULL });

	CRE_CYC(CYCHDR1, { TA_NULL, 1, cyclic_handler, CYC_TIME, 0 });
	CRE_ALM(ALMHDR1, { TA_NULL, 1, alarm_handler });

	DEF_EXC(CPUEXC1, { TA_NULL, cpuexc_handler });

	CRE_DTQ(SERVER_DTQ1, { TA_TPRI, NUM_SERVER_DTQ, NULL });
	ATT_INI({ TA_NULL, 1, local_inirtn });
	ATT_TER({ TA_NULL, 1, local_terrtn });
}
/* コア2 */
CLASS(TCL_2){
	CRE_TSK(TASK2_1, { TA_NULL, 0x20000|1, task, MID_PRIORITY, STACK_SIZE, NULL });
	CRE_TSK(TASK2_2, { TA_NULL, 0x20000|2, task, MID_PRIORITY, STACK_SIZE, NULL });
	CRE_TSK(TASK2_3, { TA_NULL, 0x20000|3, task, MID_PRIORITY, STACK_SIZE, NULL });
	CRE_CYC(CYCHDR2, { TA_NULL, 2, cyclic_handler, CYC_TIME, 0 });
	CRE_ALM(ALMHDR2, { TA_NULL, 2, alarm_handler });
	DEF_EXC(CPUEXC2, { TA_NULL, cpuexc_handler });
}

TOPPERS仕様のプロセッサアフィニティ(プロセッサクラス)の概念

静的APIのプロセッサクラスは、デフォルトの初期起動コアと、実行可能なコアの制約(例:コア1とコア3で実行可能、初期起動コアはコア3)を定義することができます。

設定したデフォルトの初期起動コアは、mact_tsk()、mact_tsk() マルチコア拡張APIにより、制約の範囲内でオーバーライドが可能です。

【mact_tsk 割付けプロセッサ指定でのタスクの起動】
 ER ercd = mact_tsk(ID tskid, ID prcid)

実行中タスクのコア移動に関するTOPPERSのポリシー

TOPPERSカーネル自体は、実行中タスクをコア移動する機能を持ちません。これは、実行中タスクのコア移動はCPUオーバヘッドが大きく、それに見合ったコアを移動させる動機が組込みシステムでは見当たらないためです。

ただし、組込みアプリケーションの多様性を考慮して、例えば汎用OSのようなコア負荷のロードバランスを取りたいという潜在ニーズに対応するために、実行タスクをユーザ責任でコア移動するAPIを公開しています。

【mig_tsk タスクの割付けプロセッサの変更】
 ER ercd = mig_tsk(ID tskid, ID prcid)

TOPPERSが現時点でサポートしているアーキテクチャ

TOPPERS/FMP,FMP3の実装は以下のアーキテクチャ、プロセッサに対応した実装が公開されています。

ARMv7-A, ARMv8-A(Aarch64)、ARMv8-R、ARMv6、RISC-V(RV64)、SH2A-DUAL、NiosⅡ

3. マルチコアの事始め

シングルコアと4コアの純粋なMIPSを比較した場合、4コアだからといって計算処理能力が4倍になるわけではありません。コアローカルキャッシュ(L1キャッシュ)間のコヒーレントが動作するためであり、コアの数と全体の処理能力の増加は比例しません。

また、マルチコア化の恩恵は、ソフトウェア全体の並列化可能な割合に依存します。

マルチコアCPUを搭載した製品ボードは高価なため、評価目的では購入をためらうところがあるかもしれませんが、QEMUなどのボードエミュレータで動作するパッケージもあります。現在組み込みシステムのマルチコア版を検討されている方は、QEMUを使用しマルチコア化による恩恵を評価してみるのも良いかもしれません。


今回は、並列化の粒度やタスク依存性の考え方、さらに並列化設計の実務上のポイントまで踏み込んで、実際のシステム開発でどのように活かされているかを解説しました。

これにて全4回の連載は終了とさせていただきます。全体を通してご不明な点やご質問、実プロジェクトでの対応のご相談などございましたら、下部のお問い合わせボタンからお問い合わせください。


より詳しく技術や関連製品について知りたい方へ

お気軽相談

本コラムに関係する技術や関連する製品について知りたい方は、お気軽にご相談ください。


製品情報

RTOSソリューション

TOPPERS-Proシリーズ

TOPPERSカーネルベースの開発プラットフォームを提供
製品ページを見る

連載|組込みシステムにおけるマルチコア 第3回 並列化の限界とソフトウェアによる対策

コラムを読む

連載|組込みシステムにおけるマルチコア 第2回 ハードウェア編 ―マルチCPUとマルチコア

コラムを読む

連載|組込みシステムにおけるマルチコア 第1回 基礎編 ―並列処理が必要になってきた背景

コラムを読む

ティックレス(Tickless)とは何か?

コラムを読む

TOPPERSカーネルの時間パーティショニング機能の概要

コラムを読む

TOPPERSカーネルのメモリ保護機能の特長と、高信頼性システム開発のポイント

コラムを読む

マルチコア/マルチOS環境でのデバイス共有/コア間・OS間通信

コラムを読む

組込みLinuxの生存確認(死活監視)

コラムを読む

組込み向けハイパーバイザーSafeGの詳細解説

コラムを読む

シングル/マルチコア上でLinux/Androidの高速起動とリアルタイムOSを協調動作

コラムを読む
メニューを閉じる
一つ前に戻る