DMA転送に使う領域にはvolatileをつけよう

出典: PS3 Linux Information Site / Cell/B.E.のパワーを体験しよう

-O3などで積極的な最適化を行うと不都合が生じる場合があります。 例えばPPEでSPEがフラグを書き換えるのをwhileループで待つ場合です。

while (flag == 0);

このコードではspeがflagを0以外に書き換えるのをスピンロックして待っています。 このコードでは見かけ上flagが永久に変更されないため、-O3の最適化によって コンパイラによってwhileループの外に出されます。その結果このwhileループは無限ループとなります。 コンパイラはflagがspeによって書き換えられるだろう事を知り得ません。 従って正しく動作させるためにはflagにvolatileをつけてコンパイラの最適化を抑制します。

同様にSPEではこのようなコードが危険です。

do
{
    spu_mfcdma32 (&arg,
                  arg_ea,
                  sizeof(arg),
                  0,
                  MFC_GET_CMD);
    spu_writech (MFC_WrTagMask, 1<<0);
    spu_mfcstat (MFC_TAG_UPDATE_ALL);
} while (arg[0] == 0);

このargは do{} while ()ループの中で参照されており、最適化してもwhileループの外に出されないような気がしますが、実際にはvolatileをつけないと正常に動作しません。

ただし最近の spu-g++ 4.0.2 ではvolatileをつけなくても正常に動作します。



Cellプログラミングのレシピに戻る

表示
個人用ツール
Open Source Projects