デュアルコア・キャッシュの一貫性

ADSP-BF561はBlackfinコアを二つ持っています。当然、この二つのコアの間で通信を行いたいといった場面は煩雑に現れます。通信の要求はコア間の割り込みで通知できるとして、実際のデータの受け渡しも必要になります。簡単な方法としてすぐに思いつくのは共有メモリを解する方法です。しかし、この方法には問題があります。以下ではデュアルコアBlackfinのキャッシュを使う場合に起きる問題と、解決策を紹介します。

一貫性が問題になる場合

Blackfinコアの性能を引き出す方法としてキャッシュは非常に有効です。しかし、二つのコアが同じ共有変数をキャッシュすると、キャッシュの一貫性(コヒーレンシー)を保つことが出来なくなります。このようなことがおきるのは二つのコアが互いに相手がデータを更新したことを知ることが出来ないからです。

ADSP-BF561のキャッシュの一貫性について図1を見ながら説明しましょう。メモリ上に変数Zがあり、コアAとコアBのキャッシュがそれぞれ変数Zのコピーをもっているとします。このとき、コアAが変数Zを読み込むと、キャッシュ内のZが読み出されますのでメモリ上のZが変更されてもコアAがそれを知ることは出来ません。また、コアBが変数Zへ値を書き込んだ場合、キャッシュがWrite Back設定だとメモリ上のZではなく、キャッシュ上のZへ値が書き込まれます。メモリ上のZへ値が書き込まれるタイミングは予測不能です。

図1 キャッシュの一貫性

以上のようにADSP-BF561のキャッシュはコア間で一貫性を保つことができません。PentiumやAthlonといったワークステーション用のプロセッサは、マルチ・プロセッサ環境でのプログラミングを容易にするためにこういった問題を解決するハードウェアを実装しています。しかしADSP-BF561にはそのような機能はありません。

そのため、キャッシュの一貫性の維持、あるいは、問題の回避はプログラマの責任になります。

対策1:キャッシュを使わない

この問題の対策として最も簡単なものは、「キャッシュを使わない」という方法です。通信要求に対して、データの転送量が非常に小さい場合はこの方法が有効です。たとえば一回の通信要求で4バイトを渡すと考えてください。これは一回のメモリアクセスですみます。データ転送のオーバーヘッドは通信要求のオーバーヘッドよりはるかに小さいため、無視できます。

対策2:IMDMAを使う

ADSP-BF561のIMDMAは、コアクロック速度でデータを転送できるコア間専用メモリDMAです。通信要求に対して、データの転送量が大きい場合にはこの方法が有効です。たとえば、一回の通信要求で1KBを送るような場合は、プログラムでちまちま転送するよりもIMDMAでガツンと転送したほうが圧倒的に高速です。

この場合、変数Zは外部の共有メモリには存在しなくなります。双方のコアのL1 SRAM上にコピーが配置され、その一貫性をプログラマがIMDMAで保持することになります。送り側が変数を更新してからIMDMAが終了するまでの間、双方の変数は一貫性を保てなくなります。IMDMAはこの点に気をつけて使わなければなりません。

蛇足ながら、通常のMDMAはSCLK領域で動作しますが、IMDMAはCCLK領域で動作します。内部メモリ間でDMA転送を行う場合、IMDMAのほうが圧倒的に高速です。

対策3:キャッシュ操作命令を使う

キャッシュをどうしても使いたい場合には、キャッシュ操作命令を使うことになります。仮にコアBが変数Zを更新してコアAがそのデータを読みたいとしましょう。

コアBは変数Zに値を書くために次のコードを実行します。

    [p0] = R1;     // P0 にはZのアドレスが、R1には新しい値が入っている。
    FLUSH [P0];    // 変数Zを格納しているキャッシュのデータをメモリに書き出す。
    SSYNC;

FLUSH命令はポインタで与えられたアドレスを含むキャッシュラインがダーティーの場合、キャッシュデータをメモリに書き出してダーティービットをクリアします。

一方、コアAはメモリの変数Zの値を読みたい場合、次のようにします。

    FLUSHINV [P0];   // 変数Zを格納しているキャッシュを無効化する。
    SSYNC;
    R1 = [P0];       // P0 にはZのアドレスが入っている。

FLUSHINV命令はFLUSH命令の機能に加えて、キャッシュラインの中のデータを無効にします。つまり、P0で指定したアドレスのデータはキャッシュされない状態になりますので、次のロード命令で確実に変数を読むことが出来ます。

キャッシュ操作命令を使うのはどんなときでしょうか。おそらく、大きな変数の中のデータを散発的に利用し、しかも使用する場合には集中的にアクセスするような場合が考えられます。しかし、DMAを使うほうがすっきりするように思えます

Blackfin空挺団 | プログラム | EZ-KIT | コア&ペリフェラル | TOPPERS/JSP | こぼれ話 | DSP掲示板