2006-10-09

本当にマルチコアがいいんですか?

日経エレクトロニクス2006年10月9日号 に 『マルチコアが変えるソフトウェア開発』というタイトルの特別企画が載るらしい。Tech-On! の日経エレクトロニクスのサイトで、その概要を見た。

Tech-On! の記事をずっとウォッチしていると、マルチコアプロセッサの話題が目に付く。マルチコアプロセッサの記事を見るたびに自分はしっくりこない何かを感じる。

こういう「何かしっくりこない感じ」がわき出るときは必ず理由がある。これまで記憶した数々の経験や知見から構築された脳内のネットワークに刺激が与えられたときにこのような感覚はアウトプットされる。

自分の場合は最初に感覚がきて、あとからその感覚を説明する論理はなんだろうかと理由付けすることがよくある。「何かしっくりこない感じ」の論理がはっきり分からないと、もやもやした感覚だけが残り気持ち悪い。

そこで、マルチコアプロセッサの話題がなぜ自分にとって「しっくりこないのか」よく考えてみることにした。

たぶん、もやもやする最大の原因は、プロセッサをマルチにしようというのはプロセッサメーカーの都合であり、プロセッサのユーザーがプロセッサの内部をマルチにして欲しいと切望しているわけではないからだではないかと思う。単純にプロセッサがマルチになっていると、アーキテクトとしてはどのプロセッサになんのタスクを割り当てたらよいのか悩むことになる。もしかすると、その割り当ての技術がアーキテクトとしての腕の見せ所になるのかもしれないが、考えなくてもいいのなら余計なことは考えたくない。

最近マルチプロセッサが話題になっているのは、これまでシングルプロセッサでCPUの性能を上げてきたCPUメーカーが、これ以上CPUの性能を上げながら低消費電力を実現するのが難しくなってきたからだと聞いている。消費電力を押さえながらCPUの性能を高めるための技術的ブレークスルーがCPUコアのマルチ化だというのだ。ようするに、これまでのCPUアーキテクチャではこれ以上の進歩は望めないので、CPUコアをシングルからマルチにして負荷を分散させようというのだ。

しかし、組込みアーキテクトから言わせてもらえば、それはCPUの作り手側の都合であり、我々の切なる要求というわけではない。ちなみに、自分のプライベートPCのCPUは Intel の Pentium Dプロセッサで、デュアルコアプロセッサだが、たぶん、Windows アプリケーションのプログラマは、デュアルコアプロセッサの特性を活かしたアプリケーションソフトを作ってはいないと思う。

CPUがシングルかマルチなのかを気にしているとしたら、Windwos XP のOSだろう。どこかのWEBサイトで、Pentium Dプロセッサを使うのなら、XP Personal ではなく、XP Peofessonal にした方がパフォーマンスが上がる場合があると書いてあるのを見た記憶がある。

ようするに、デュアルコアプロセッサの特長を活かしているのはOSであって、アプリケーションソフトではない。もしかすると、OSもシングルコアかデュアルコアか気にしなくてもいいように、CPU側がくふうしてくれている可能性もある。

組込みの方もそういう考え方で、アプリケーションエンジニアやアーキテクトがCPUがシングルであったり、マルチであることを気にしなくていいのなら、「何かしっくりこない感じ」はしないはずだ。

ところが、日経エレクトロニクス2006年10月9日号 に『マルチコアが変えるソフトウェア開発』には、次のようなことが書いてあるらしい。

【<事例編>マルチコアに向けたソフト開発の現場から】

並列処理を意識したソフトウェア開発にとってマルチコア型マイクロプロセッサの性能を引き出した例が民生機器で登場しつつある。事例から見えてきたのは、ソフトウェア開発者がスレッドの粒度や同期の在り方にまで気を配ることの大切さである。

【引用終わり】

モデル駆動開発の用語でPIM(Platform Independent Model)と、PSM(Platform Specific Model) という言葉がある。

PIM(Platform Independent Model)はプラットフォームから独立したプラットフォームに依存しないモデルで、PSMはプラットフォームに依存したモデルを意味する。

PIMはプラットフォームから独立しているので、プラットフォームが変化してもモデル自体が変わらない、だから寿命が長い。モデル駆動開発では、ユーザー要求をプラットフォームに依存しないPIMとして記述し、プラットフォームに依存する実際に実装するためのPSMはツールを使ってモデル変換できるようにしようと考えている。

実は、自分はこのモデル駆動開発の支持者ではない。モデル駆動開発がうまくいってしまうと、組込みアーキテクトが職を失ってしまうという危機感もあるが、それ以上に組込みの場合、ユーザー要求を最適化することがツールで簡単にできるとは思えないからだ。

しかし、だからといって、PIM(Platform Independent Model)が重要でないとは言わない。PIMを目指す重要性は十分分かっている。プラットフォームに依存したモデルばかり設計していると、ハードウェアやプラットフォームの変更があるたびにソフトウェアを修正しなければいけない。それは効率的でないし、ソフトウェアエンジニアの首を絞めることにつながる。

だから『組込みソフトエンジニアを極める』では、ユーザー要求を性能的な面で実現させる PSM的ボトムアップの視点と、ユーザー要求を機能的な面で実現させる PIM的トップダウンの視点の両方の視点を持つことだ大事だと書いた。

ここで、PSM的ボトムアップの視点を考慮すると言っているのは、製品の機能や性能を実現するためのキーデバイスの特性を考慮することを想定しているのであって、CPUアーキテクチャを考慮することが重要だと言っているのではない。

CPUが変更されたとしても、できるだけアプリケーションソフトウェアは変更しないでよい作りになっていた方がよいと考えている。

なぜなら、CPUは製品の価値を実現するための直接的なデバイスではないと思うからだ。CPUの機能や性能は製品の価値を高めるために間接的に関与するが、パフォーマンスや消費電力などを満たすことができるならばなんでもいい。

T-Engine ではアプリケーションソフトは 明確にCPUから Independent であることを目指している。

そう考えると、 “マルチコア型マイクロプロセッサの事例から見えてきたのは、ソフトウェア開発者がスレッドの粒度や同期の在り方にまで気を配ることの大切さである。” は、PIM を目指そうと考えるソフトウェアエンジニアから見ると PIMからPSMへ逆戻りしているように見える。

マルチコアでもCPU+DSPのような組み合わせは、それほど「もやもや」しない。なぜなら、DSP(Digital Signal Processor)は画像の圧縮・伸張や、デジタルフィルタなどの信号処理に適しており、CPUの役割とは異なり処理を分離することがユーザーの直接的な利益につながるように思えるからである。

そう考えると、同じCPUコアを複数搭載し、どちらのCPUコアにどのタスクを割り当てるべきかを考えるのは、組込みアーキテクトにとって余計な作業であり、どんなに上手に割り当てを行ってもユーザーに直接的なメリットをもたらすように思えないのだ。

たとえば優先度の高いタスクをデュアルコアの片方のCPUに割り当てるという方法はある。でも、よく考えて欲しい。それは組込みソフトエンジニアから見れば、リアルタイムOSを使ってタスクを分割し、タスクの優先度変えることで、限られたCPUパフォーマンスを最適化してきたのと何ら変わりないように見える。

リアルタイムOSでタスクの優先度を変えるのは簡単だが、デュアルコアでCPUに対してのタスクの割り当てを変えるのは簡単ではないように思う。さらにデバッグのことを考えると頭が痛い。CPUが分かれていると同期を取りながらデバッグするのはとても難しいだろう。シングルチップなら、突き詰めれば処理はシーケンシャルなのでなんとかデバッグもできる。

だから、マルチコアプロセッサを選択しようとしている方達にタイトルのような「本当にマルチコアがいいんですか?」という質問をしたいのだ。

一番危ないのは、アプリケーションやシステムの構造がどんなに無駄な動きをしていてもCPUの性能をどんどん高くしていけば、製品の機能性や性能をカバーできてしまうと考えてしまうことだろう。

ソフトウェアは見えにくいだけに、アーキテクチャの悪さが外からは見えないことも多い。シングルコアとRTOSの使い方のくふうで十分にユーザー要求を満たすべく、機能・性能を最適化できるにもかかわらず、CPUの性能を上げることで強引に解決してしまおうと考えるのは、本質的な問題に蓋をして表面的なくふうでその場をしのごうとしているようにも思える。リアルタイムアーキテクチャーを実現するための道具としてのリアルタイムOSも十分に使いこなせていないのに、安易にマルチコアプロセッサという解決策へ逃げているように見えるのだ。

また、「何かしっくりこない感じ」の原因は、作り手側の都合が先行していて、ユーザーへの価値を最大にするという考えに基づいていないように思えるからかもしれない。

もしも、デュアルコアプロセッサで成功しているプロジェクトがあるのなら、それはデュアルコアであることを製品の価値を高めることに結びつけることに成功しているからに違いない。ようするに、その製品はデュアルコアプロセッサを使う必然性がある筈なのだ。

だから、必然性もないのに最近の流行だからといってデュアルコアプロセッサを選択するのは危険なにおいがする。

3 件のコメント:

匿名 さんのコメント...

SMPなマルチコアCPUの場合、OSがきちんと対応していれば、マルチコアかどうかをアプリが意識する必要はないはずです(非常に大雑把な議論かもしれませんが)。T-Kernelは、SMP/AMPどちらも対応している(する計画)のですが、今話題なのはSMPだと思いますから、基本的にはマルチコアを意識せずに速度アップができます。(ご指摘のようにCPUが意識するから)

"ソフトウェア開発者がスレッドの粒度や同期の在り方にまで気を配ることの大切さ”の”同期”については、以下の意味ではないかと思います。

シングルコアなCPUの場合は、マルチタスクOSといえども、真に同時に複数タスクが動作することがありません。一方、SMPなOSの場合、本当に同時にタスクが動作してしまいシングルコアでは発生しなかったリソースの競合が発生したりします。そのため、同期機構を見直す必要が出てくることがあります。これは、組込みに限らず、LinuxでもWindowsでもあった一般的な話です。

スレッドの粒度はともかく、同期のあり方に気を配るのは、マルチコアでもシングルコアでも当然の話だと思います。雑誌が指摘しているのは、マルチコアでは(本来きちんと同期しているものならば)シングルコアのタスクがそのまま使用できるようにOS/CPUが出来ているにもかかわらず、問題が発生してしまう(潜在的な問題が顕在化する)ということを指しているのではないでしょうか。

sakai さんのコメント...

うさみさん、コメントありがとうございます。当ブログにおいて栄えあるお二人目のコメントです。

SMP(Symmetric Multiple Processor)対称型マルチプロセッサとASMP(Asymmetric Multiple Processor)非対称型マルチプロセッサについてよく知らなかったので勉強になりました。

シングルコアでも同期に気を遣わないといけないというのはそのとおりだと思います。

シングルコアでRTOSを使う場合、RTOSのタスクは疑似並列処理になります。本当はCPU一個なのに、作り手側のプログラム記述はあたかも複数のCPUが動いている気分でソースを書くことができます。

実際に調停してくれるのは RTOS であり、RTOSが内部でやってくれていることをRTOSのユーザーはあまり気を遣わなくてもよいということになります。

SMPなマルチコアプロセッサの場合はどうなんでしょうか。OSが全部請け負ってくれていて、プログラマはプロセッサがシングルかマルチか気にしなくてもいいのならいいのですが、シングルコアでRTOSがやってくれていた仕事についても考えなくてはいけなくなるのなら、その対価としてエンドユーザーに対するユーザーメリットが欲しいものです。

プロセッサAに割り当てていたタスクAをタスクBに割り当てを変えることが簡単にでき、うさみさんご指摘のリソース競合などをうまく処理してくれる機構があればいいのですが、そこにまで気を遣わなければいけないとなると大変かなと感じてしまいます。

匿名 さんのコメント...

たまたま、マルチコアOSで検索がかかった 通りすがりですが、実際にITRONカーネルの実装を生業にしているものです。
先週ちょうど名古屋(NEP)でマルチプロセッサRTOSの内部構造という講座があったので勉強してきたものです。

ただ、貴殿の「何かしっくりこない感じ」というのは、自分も感じています。また汎用OSについては、マルチコアかどうかについてはOS側がやることで、アプリケーションがあまり考えなくてよくて、リアルタイムシステムにおいては、アプリケーションで対策が必要なことが現状ですね。
だから日経の記事も間違っていません。T-engineやT-kernelのマルチコア対応がどこまでのものなのかはよくわかりませんが、マルチコアOSにおける、リアルタイム性とスループットはトレードオフが必要なものですね。これはまだひょっとすると将来打開できるハードルなのかもしれませんが。

具体的にどういうことかとできるだけ簡単に書くと、タスクをどのコアで実行するかとユーザーが指定しないタイプのOSだと、OSが負荷に応じて空いているコアに切り替えて負荷分散します。これ自身に時間がかかること、さらにこれがリアルタイムシステムにおいては頻発する場合もあり、さらに最大の問題はCPUキャッシュが切り替えた場合ではキャッシュが上手く使えないことがあります。つまり同じ速度のシングルコアよりも最優先タスクでは速度低下することになります。講義でやったのは、ユーザーがどのタスクがどのコアで実行するのかを指定するタイプなのでユーザーがマルチコアを最適に利用する必要があるということになります。

また、タスク間通信においても、コアまたぎがある場合は、コア間の排他制御でのスピンロックという方法をとるため、待たされるコアはスピンロックでぶんまわさないといけなくなります。これが実行時間が読めなくなり、いわゆるリアルタイム性能に影響が発生します。なので、可能な限りスピンロックで待たされないようにするために共有リソースを減らせば無駄なループを減らすことができます。なので、どういったタスクをどのコアに配置し、どの同期オブジェクトをコアで共有するかという設計が重要になります。

貴殿のPIMとは逆行した設計が必要になると思うし、まだマルチコアRTOSは今の時点においても発展途上のものという感じはしますね。