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.

```
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 `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.

```
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.

```
 \*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 *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
--------

1. ↑  FOLDOC'un yorumuyla Duff aygıtı[*ölü/kırık bağlantı*]

Bibliyografya
-------------

* Stroustrup, Bjarne, *C++ Programlama Dili, Üçüncü Baskı*. Addison-Wesley, ISBN 0-201-88954-4
* Kernighan, Brian ve Dennis Ritchie, *C Programlama Dili*.

Dış bağlantılar
---------------

* Duff'ın özgün mektubu 22 Ocak 2009 tarihinde Wayback Machine sitesinde arşivlendi.
* FOLDOC'ta konuyla ilintili bir yazı
* Jargon File'da konuyla ilintili bir yazı 21 Ekim 2008 tarihinde Wayback Machine sitesinde arşivlendi.
* CodeMaestro'da konuyla ilintili bir yazı
* Özgün USENET gönderisinin Google kopyası 22 Mart 2009 tarihinde Wayback Machine sitesinde arşivlendi.
* Simon Tatham'ın C'deki eşyordamları9 Kasım 2019 tarihinde Wayback Machine sitesinde arşivlendi. aynı switch/case hilesini kullanmaktadır
* Adam Dunkels'ın işleçleri13 Ekim 2005 tarihinde Wayback Machine sitesinde arşivlendi. de aynı switch/case ifadelerini kullanmaktadır
* Duff aygıtının doğrulaması
* C'deki Hafif ve Yığıtsız İşleçler13 Ekim 2005 tarihinde Wayback Machine sitesinde arşivlendi. (ayrıca bkz. En hafif işleçler25 Temmuz 2010 tarihinde Wayback Machine sitesinde arşivlendi.)