2009-05-03 11 views
6

何年も前にタイトなグラフィックスI/Oの問題に取り組んでいる間、トム・ダフは、ループをアンロールし、次のように彼のDuff's Deviceを作成:Duffのデバイスは他の言語でも動作しますか?

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int 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); 
    } 
} 

を(これは古いスタイルの関数パラメータを使用します - それはエラーではありません。)

このコーディングは、C言語でのアセンブラとコーディングではまったく考えられず、Cのcase文のフォールスルーに依存しています。インターレース制御構造のこのような創造性は他の言語でも使えますか?

+0

「旧式関数のパラメータ」とは何ですか? –

答えて

4

あなたが計算されたGOTO文をサポートしている任意の言語(Fortranの、いくつかの基本、など)でそれを行うことができます

+0

しかし、GOTOも飛び越えるべきアドレスを動的に計算できないなら、それは本当にそれほど価値がないので、面倒です。だから私はそれがPHPのような動的言語で良いアイデアだとは思わない... –

3

これはC++で動作します。

生成されるコードはコンパイラによって異なりますが、特に、GCCターゲティングのARMアーキテクチャを使用してDuffのデバイスをコンパイルすると、結果として得られるARMアセンブラは最適化レベルでは最適ではありませんでした(GCCはこれをジャンプテーブルに変えました)。

アセンブラのコードを渡すだけでした。

+3

コンパイラがあまり最適化しなかったとき(Duffがそれを思いついたとき)は良かったです。問題は、すべてのステップでドロップスルーフローと 'case'ラベルの両方があり、レジスタなどをフラッシュする必要がないことを確認する非常に優れたコンパイラが必要だということです。とにかく素朴な実装のループを展開することができます。 でも良い面接の質問をする:) –

2

ダフのデバイスである、本質的に計算された他の多くの言語で行うことができますgoto - アセンブリ(もちろん) FORTRANはそれらを直接サポートするカップルです。

2

大規模な配列処理を高速化するためにJavaScriptで非常にうまく使用しました。私はC#でそれを使うことができたらいいと思う。

dsend(to, from, count) 
char *to, *from; 
int count; 
{ 
    int n; 
    for(n=0; n!=count/8; n+=8){ 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
     *to = *from++; 
    } 
    for(; n!=count; n++) 
    { 
     *to = *from++; 
    } 
} 

確かにこれはcount小さいと多少遅くなりますが、それは非常に、ややポータブル言語間でやや読みやすいですし、生成します。それはあなたがまだ二つのループを有していてもよく、この方法は使用できない場合でも

+2

することができます。クリーンアップ・ケースをループと同じにする必要はありません。アンロールされたループをn/8回実行し、最後に7つの条件ステップを実行します。大規模な配列の場合、最後の7つの小さな非効率性はノイズの中で失われます。 –

+3

Paul、クリーンアップのケースがループと同じでない場合、私はそれがもうDuffのデバイスと呼ばれることは間違いないと思います。 Duffのデバイスは、ループのアンローリングだけではありません。これは、 'switch'ステートメントを使用して、展開されていないループの途中にジャンプします。 –

0

同様の利益を大きいcountとする。

関連する問題