マルチコアにより処理分割を行う際には、必ずオーバーヘッドが存在します。逐次実行の場合には命令を順番に実行しますが、マルチコア環境においては「処理の起動」「処理が実行するために必要な情報の引き渡し」「処理の終了」「処理の終了結果の情報」などさまざまな情報のやりとりをコア間で行う必要があるため、オーバーヘッドが発生します。
当然ながらオーバーヘッドは少なければ少ないほど良い性能が期待されます。オーバーヘッド時間が同じであると考えると、処理時間が長い部分を分割した方がオーバーヘッドは少なくて済むので、良い性能が期待されます。例えばmain()から、sub1()がコールされ、さらにsub1()からsub2()が10回コールされていたとします。するとmain()からsub1()がコールされる部分で分割を行った場合(1)ではオーバーヘッドが1回で済みますが、sub1()とsub2()で分割が行われた場合(2)ではオーバーヘッドが10回発生します。
ここでは「起動オーバーヘッド時間」を100μSEC、「終了オーバーヘッド時間」を100μSECとしてオーバーヘッド時間を計算します。main()からsub1()がコールされる部分で分割した場合(1)は1回のみコールされるため、オーバーヘッドは合計200μSECになります。また、sub1()からsub2()がコールされる部分で分割した場合(2)では10回コールされるため、オーバーヘッドは10倍の2m(2000μ)SECとなります。従って分割ポイントとしては、なるべく親関数に近い部分おいて分割を検討するべきであるといえます。
ソフトウェアにおいて処理結果が同一関数の場合とそうでない場合、その依存関係について考慮する必要があります。処理結果が同一関数の場合は関数分割が行われても内部変数に格納されますが、処理結果が同一関数内でない場合は外部変数もしくは関数のリターン値などに格納されます。
また一般的にシーケンス処理と呼ばれるものは、並列化を行った際に処理性能の向上が期待できません。各処理についてその前処理結果が出るまで待ち続ける必要があるためです。例えば「処理1」と「処理2」という2つの処理が存在する場合、「処理2」は「処理1」の結果を演算に使用する場合など、「処理1」と「処理2」をコア分割して並列化した際に「処理2」は「処理1」の結果を待ち続けてしまいます。
デットロックは、マルチコア(並列化)における問題として最も一般的なものです。複数のプロセスそれぞれが必要とするリソースをお互いにロックし、必要なリソースが開放されるまでお互いにロック(待ち)状態になることを示します。つまり、お互いにロックされていて動作ができない状態です。以下にデッドロックの簡単な例を記します。
処理1がロックBの資源を要求しても、すでに処理2が保持しているため、ロック状態となります。また、処理2がロックAの資源を要求しても、すでに処理1が保持しているため、ロックされた状態となります。よってお互いが待ち状態となり、動作ができない状態となります。
Copyright © ITmedia, Inc. All Rights Reserved.