マルチコアでは、スーパーリニアといって、コア数を超える性能向上が得られる場合があります。
スーパーリニアはリソースが増えたことにより起こります。例えば、シングルコアの時と比べて2コアではキャッシュが2倍になりますが、それが良い影響を及ぼすことがあります。
例として、大きな配列を扱う処理があり、配列全体は一つのプロセッサのキャッシュに載らないが、分割すれば二つのプロセッサのキャッシュに載るようなケースを想定します。また、キャッシュがヒットする場合はミスする場合と比較して処理が2倍高速になるとします。このとき、下の図のように、シングルコアではデータサイズが大きいため常にキャッシュミスすると仮定し、全体で100の処理量があるとします。2コア実行で、そのままキャッシュミスする場合、理想的には2倍の高速化ですが、データが各プロセッサのキャッシュにすべて載ったことにより、さらに2倍高速化し、全体で4倍の高速化になります。このような場合、前回までに説明したオーバーヘッドの影響があっても、コア数よりも高速化することがあります。
ここで、読者の皆さんは「それならば、シングルコアで動作している段階から、データを分割するなど計算順序の工夫によってキャッシュヒット率をあげることができ、そうすればスーパーリニアにはならなかっただろう」と考えると思います。おそらくその通りでしょう。
つまり、シングルコアでもマルチコアでも、近年のプロセッサでは「データが動かないようにすること」が極めて重要である、ということです。マルチコアではプロセッサ間でデータ移動するコストが大きいため、より大きく影響します。
このことは前回説明した依存関係の話と密接な関係があります。依存関係を持つ2つの処理は、異なるプロセッサに処理を配置しても並列動作することはなく、同一のプロセッサに割り当てることをまずは考えますが、一方の処理で生成されたデータを他方で使用するような依存関係の場合、同一プロセッサに割り当てることはキャッシュ効率を上げることにもなります。すなわち、マルチコア向け並列化では、依存関係を考慮して、計算のコア割当だけでなく、データのコア割当も考えることが重要となります。
コメントをお書きください