仕事で使うコードの最適化について考えていたら、ふと、Duff's deviceが思い浮かんだ。仕事で使うコードとはまったく関係ないんだけど。
Duff's deviceは以下のようなコードである(Wikipedia英語版から若干修正)。
void strcpy(register char *to, register char *from, register count) { register n = (count + 7) / 8; switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); } }
要は、switch文のfall-throughを利用したループ展開による効率の良いメモリコピーだ。因みに、上記のコードで to に対してインクリメントがされていないが、出力レジスタへのコピーなのでこれで正しい。
効率的だといってこのコードを普段から利用するのはあまり良いとは云えないと思う。可読性が良いわけではないし、最近のコンパイラは最適化が進んでいることもあり、場合によっては速くならないことも考えられる。個人的には、このコードはswitch文におけるfall-throughの端的な例として見せるに留めるのが良いように思う。
Duff's deviceは以下のようなコードである(Wikipedia英語版から若干修正)。
void strcpy(register char *to, register char *from, register count) { register n = (count + 7) / 8; switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); } }
要は、switch文のfall-throughを利用したループ展開による効率の良いメモリコピーだ。因みに、上記のコードで to に対してインクリメントがされていないが、出力レジスタへのコピーなのでこれで正しい。
効率的だといってこのコードを普段から利用するのはあまり良いとは云えないと思う。可読性が良いわけではないし、最近のコンパイラは最適化が進んでいることもあり、場合によっては速くならないことも考えられる。個人的には、このコードはswitch文におけるfall-throughの端的な例として見せるに留めるのが良いように思う。
コメント