Duff aygıtı

Berimsel bilimlerde **Duff aygıtı**, Assembly Dilinde yüksek başarıma izin veren döngü çözme tekniğini kullanan seri kopyalama yordamına ait bir uygulamadır. Tom Duff'ın Lucasfilm'de görev yaptığı Kasım 1983'te bulguladığı yöntem, C programlama dilindeki switch yapısının en ilginç kullanımlarından birini oluşturmaktadır. Duff, yalnızca bu yöntemi bulguladığını savunmakta ve genel döngü çözme yöntemi üzerinde herhangi bir hak iddia etmemektedir.

## Özgün sürüm
Seri kopyalama işleminin olağan uygulaması aşağıdaki gibidir.


```cpp
do { /* count > 0 koşulunun sağlandığı varsayılıyor */
    *hedef = *kaynak++;       /* ''hedef'' imleci artırılMAmaktadır */
} while (--toplam > 0);
```


`hedef` imlecinin artırıl*ma*masının nedeni Duff'ın kopyalama için tek yazmaç kullanıyor olmasıdır. Bu işlem, `hedef` imlecinin `[[gelgeç değişken|volatile]]` ifadesiyle tanımlanmasıyla da yerine getirilebilir.

Duff, bu betiğin başarımını artırmaya çalışırken bunun switch ve döngü yapılarını *iç içe geçirmek*le de sağlanabileceğini görmüştür.


```cpp
dsend(hedef, kaynak, toplam)
char *hedef, *kaynak;
int toplam;
{
    int n = (toplam + 7) / 8;
    switch (toplam % 8) {
    case 0: do { *hedef = *kaynak++;
    case 7:      *hedef = *kaynak++;
    case 6:      *hedef = *kaynak++;
    case 5:      *hedef = *kaynak++;
    case 4:      *hedef = *kaynak++;
    case 3:      *hedef = *kaynak++;
    case 2:      *hedef = *kaynak++;
    case 1:      *hedef = *kaynak++;
               } while (--n > 0);
    }
}
```


Bir kopyalama işlemi sırasında gerekli karşılaştırma sayısını en aza indirgemeye yarayan assembly yordamını temel alan Duff aygıtı, C'de uygulandığında açık bir fark yaratmıştır. *Switch* ifadesinin dildeki esnek tanımı bu yöntemin C'nin tüm kurallarıyla uyuşmasına yardımcı olmuştur. Aygıtın bulgulanması C Programlama Dili'nin ilk baskısından hemen sonraya rastlamakta ve aygıtın sözdizimi kitapta öngörülen switch kullanımıyla örtüşmektedir. *Break* ifadesinin bulunmadığı switch betiklerinde akışın kesintisiz biçimde sürdüğü göz önüne alındığında Duff aygıtının sıralı kaynaklardan çıktı yazmaçlarına *toplam* kopyaları aktardığı görülür. Burada, *toplam* değişkeninin 0'dan büyük olması zorunludur.

Çoğu derleyici switch'i bir sıçrama tablosuna çevirecektir. C'nin case ifadesindeki öntanımlı akış yordamı dilin en çok tartışılan özelliklerindendir. Duff bu konuda şunları söylemiştir: "Bu betik, tartışmaya bir yerden giriyor ancak bunun olumlu mu olumsuz mu olduğu konusunda emin değilim."

Hızı artıran ana etken bir döngü içinde yapılan karşılaştırmaların sayısını azaltan döngü çözme yöntemidir. Switch/case ifadesi toplam verinin çözülen işlem sayısına bölümünden kalan kısmını işlemektedir (8'li döngü çözmenin uygulandığı örnekte switch/case ifadesi kalan 1–7 baytlık bölümü hedef almaktadır).

Kalan bölümün bu biçimde işlenmesi tüm sistem ya da derleyicilerde aynı başarımı göstermeyebilir. Kimi durumlarda iki ayrı döngü (ilk döngü ana kopyalamayı yaparken ikinci döngü kalan veriyi işler) kullanmak daha iyi sonuç verebilir. Sorun, derleyicinin aygıtı doğru bir biçimde hızlandırmasına indirgenebilir ancak bu kullanımın kimi sistemlerde ardışıklama ve sıçrama tahminini olumsuz etkileyebileceği düşünülmektedir. Bu nedenle, bu aygıtın birlikte kullanılacağı sistem, hızlandırma değişkenleri ve derleyicinin iyi seçilmesi gerekmektedir.

## Stroustrup uyarlaması
Bir konumdan diğerine kopyalama yapabilmek için *hedef* imlecinin aşağıda gösterildiği gibi sürekli artırılması gerekmektedir.


```cpp
*hedef++ = *kaynak++;
```


Aygıtın bu sürümü Bjarne Stroustrup'un *C++ Programlama Dili* adlı kitabının "Bu Kod Ne Yapıyor?" bölümünde, dille yeni tanışan programcılara çıktı yazmaçlarının işlevleri hakkında bilgi vermek amacıyla gösterilmiştir. Ne var ki, C kütüphanesinde bulunan *[[string.h|memcpy]]* işlevi tam olarak bu işi yapmaktadır. Farklı sistemler için başarım artırıcı teknikler içeren bu işlev yukarıda gösterilen betikten daha hızlı çalışmaktadır.

## Kaynakça

## Bibliyografya
* Stroustrup, Bjarne, *C++ Programlama Dili, Üçüncü Baskı*. Addison-Wesley, ISBN 0-201-88954-4
* Kernighan, Brian ve Dennis Ritchie, *[[C Programlama Dili (kitap)|C Programlama Dili]]*.

## Dış bağlantılar
* Duff'ın özgün mektubu 
* FOLDOC'ta konuyla ilintili bir yazı 
* Jargon File'da konuyla ilintili bir yazı 
* CodeMaestro'da konuyla ilintili bir yazı 
* Özgün USENET gönderisinin Google kopyası 
* Simon Tatham'ın C'deki eşyordamları aynı switch/case hilesini kullanmaktadır
* Adam Dunkels'ın işleçleri de aynı switch/case ifadelerini kullanmaktadır
* Duff aygıtının doğrulaması
* C'deki Hafif ve Yığıtsız İşleçler (ayrıca bkz. En hafif işleçler)