実用的なループ展開手法の例を見つけています。
ダフのデバイスはいいヒントだと思います。
しかし、ダフのデバイスの目的地は決して増加しません。一般的なプログラマーではなく、シリアルデバイスにデータをコピーする組み込みプログラマーに役立つ可能性があります。
素敵で便利な例を教えてください。
実際のコードで使用したことがある場合は、より優れたものになります。
実用的なループ展開手法の例を見つけています。
ダフのデバイスはいいヒントだと思います。
しかし、ダフのデバイスの目的地は決して増加しません。一般的なプログラマーではなく、シリアルデバイスにデータをコピーする組み込みプログラマーに役立つ可能性があります。
素敵で便利な例を教えてください。
実際のコードで使用したことがある場合は、より優れたものになります。
最も実用的な手法は、コンパイラの最適化オプションを学習して気に入り、プロファイリングでホットスポットに遭遇した場合は、生成されたアセンブリを手動で検査することです。
「目的地が増えない」というのが何を意味するのかわかりません。
手動でループを展開することはあまり一般的ではありません。今日の組み込みマイクロプロセッサは十分に高速であるため、そのような最適化は必要ありません (また、貴重なプログラム メモリが無駄になります)。
線形ソルバー カーネルで Duff のデバイスのバリエーションを使用します。back_step
各に1 つ必要でfwd_step
、4 人ずつのグループで実行されます。
順方向ループと逆方向ループは s によって実装されていることに注意してくださいgoto
。if
infwd_step
をスキップすると、実行は後方ループの途中にジャンプします。つまり、これは一種のダブルダフの装置です。
これは「実用的な」テクニックではなく、非常に複雑なフロー制御を表現するための最良の方法です。
switch ( entry ) {
#define fwd_step( index ) \
\
case (index): \
if ( -- count ) { \
...
startf:
fwd_step( 0 )
fwd_step( 1 )
fwd_step( 2 )
fwd_step( 3 )
stream = stream_back;
goto startf;
#define back_step( index ) \
.... \
} \
startb:
stream -= block_size;
back_step( 3 )
if ( ! -- countb ) break;
back_step( 2 )
if ( ! -- countb ) break;
back_step( 1 )
if ( ! -- countb ) break;
back_step( 0 )
if ( -- countb ) goto startb;
} // end switch
(他の人のために、ダフのデバイスの背景はこことここで見つけることができます)
特に、完全なタイルまたはカーネルよりも少ないピクセルがコピーされる境界条件を処理するために、画像処理の最適化で遭遇しました (これにより、各座標でのテストを回避できます)。