それはダフのデバイスではありません。特別なプレループアライメントステップを使用します(これはまさにDuff's Deviceが回避するように設計されているものです)。
真のDuff'sDeviceには、ロールされていないコードの1つのセクションがあり、最初は。によって部分的にスキップされswitch
ます。このトリックは、必要なコードの量を(ループだけに)減らし、コード内の条件付きジャンプの数を減らします。
提示したコードは、単に手動で展開されたループです。
ループ展開:
ループ展開は、ループの複数の反復が一度に処理される最適化手法です。したがって、代わりに:
$number_of_iterations = 128;
for ($n = 0; $n !== $number_of_iterations; ++$n) {
do_something();
}
あなたが使う:
$number_of_iterations = 128;
for ($n = 0; $n !== (int)($number_of_iterations / 4); ++$n) {
//Repeat do_something() four times.
//Four is the "unrolling factor".
do_something();
do_something();
do_something();
do_something();
}
これの利点はスピードです。条件付き分岐は通常、比較的コストのかかる操作です。展開されたループと比較して、最初のループは条件分岐を4倍頻繁に通過します。
残念ながら、このアプローチには多少問題があります。4で割り切れ$number_of_iterations
なかったとしましょう-分業をより大きな塊に分割することはもはや機能しません。これに対する従来の解決策は、展開されたループによって残りの作業量を実行できるようになるまで、より小さなチャンクで作業を実行する別のループを作成することです。
$number_of_iterations = 130;
//Reduce the required number of iterations
//down to a value that is divisible by 4
while ($number_of_iterations % 4 !== 0) {
do_something();
--$number_of_iterations
}
//Now perform the rest of the iterations in an optimised (unrolled) loop.
for ($n = 0; $n !== (int)($number_of_iterations / 4); ++$n) {
do_something();
do_something();
do_something();
do_something();
}
これは優れていますが、最初のループは依然として不必要に非効率的です。これもまた、反復ごとに分岐しています。これは高価な提案です。でphp
、これはあなたが得ることができるのと同じくらい良いです(??)。
次に、Duff'sDeviceと入力します。
ダフスデバイス:
効率的な展開ゾーンに入る前にタイトなループを実行する代わりに、別の方法は、展開ゾーンに直接移動することですが、最初はループの途中にジャンプします。これはDuff'sDeviceと呼ばれます。
言語をに切り替えC
ますが、コードの構造は非常に似ています。
//Note that number_of_iterations
//must be greater than 0 for the following code to work
int number_of_iterations = 130;
//Integer division truncates fractional parts
//counter will have the value which corresponds to the
//number of times that the body of the `do-while`
//will be entered.
int counter = (number_of_iterations + 3) / 4;
switch (number_of_iterations % 4) {
case 0: do { do_something();
case 3: do_something();
case 2: do_something();
case 1: do_something();
while (--counter > 0)
}
以前のfromのすべての条件分岐は、while ($number_of_iterations % 4 !== 0)
(スイッチからの)単一の計算されたジャンプに置き換えられました。
この分析全体は、コードの領域内の条件分岐の数を減らすと常にパフォーマンスが大幅に向上し、コンパイラーが適切な場合にこの種のマイクロ最適化を単独で実行できないという欠陥のある概念に基づいています。最新のコードでは、手動ループ展開とDuff'sDeviceの両方を回避する必要があります。