İki kart arasında kamera karesi taşırken hattın hızı çoğu zaman sorun değildir; sorun, kareyi kimin taşıdığıdır. Veriyi işlemci bayt bayt kopyalıyorsa PCIe hattı kapasitesinin küçük bir kısmında çalışır ve o çekirdek başka iş yapamaz. Taşıma işi denetleyicinin içindeki DMA motoruna verildiğinde işlemci yalnızca "şuradan şuraya, şu kadar" der, gerisini donanım yapar. Tezgâhımızda bir TI Jacinto 7 (J784S4) ile bir Jetson AGX Orin arasında, PCIe Gen3 ×4 üzerinden DMA ile 3,0–3,2 GB/s ölçtük; aynı hatta DMA, işlemcinin yaptığı kopyadan yaklaşık 8 kat hızlı çalıştı. Bu yazı o farkın nereden geldiğini ve hangi ayarların onu belirlediğini anlatıyor.

Kısaca

  • Kareyi işlemci kopyalarsa darboğaz hat değil işlemcidir. DMA'da işlemci aktarımı yalnızca tarif eder; veriyi denetleyici taşır.
  • PCIe Gen3 ×4'ün ham tavanı yön başına 3,94 GB/s'dir. Paket başlıkları bunun bir kısmını alır; azami yük boyutunu 128 bayttan 256 bayta çıkarmak paket verimini yaklaşık %86'dan %92'ye taşır.
  • DMA'nın sabit bir hazırlık bedeli vardır. Birkaç kilobaytlık aktarımda işlemci kopyası öne geçebilir; bant genişliğinden "kare başına süre" türetmek bu yüzden yanıltır.
  • Ölçtüğümüz: 3,0–3,2 GB/s ve yaklaşık 8 kat. Ölçmediğimiz: dört Orin'li hattın uçtan uca gecikmesi.

Görüntü ve arkasındaki iş

64 saniyelik görüntümüz Straight to the GPU tek bir kareyi izliyor: kare Jacinto'ya iniyor, PCIe üzerinden Orin'in belleğine yazılıyor, dört Orin sırayla stabilizasyon, görüntü iyileştirme, nesne takibi ve gösterge okuma yapıyor, sonra kare Jacinto'ya dönüp WebRTC ile operatörün ekranına gidiyor. Ardından aynı kartlar ve aynı kablo, bu kez her kareyi işlemci kopyalarken gösteriliyor.

Fabrika, dört Orin'li hat ve kontrol odası 3B illüstrasyondur; veri yolları ve tespitler canlandırmadır. Gerçek olan, iki kart arasındaki sürücü işi ve onun tezgâh ölçümüdür: bir Jacinto 7 (J784S4) kök tarafta, bir Jetson AGX Orin uç nokta tarafında, aralarında PCIe Gen3 ×4. Orin'in uç nokta olarak çalışması NVIDIA'nın belgelediği bir kiptir. Sürücüyü iki tarafta da biz yazıyoruz. Dört Orin'li bir hattı kurup ölçmedik.

Kare neden kopyalanır, kopyayı kim yapar?

İki kart PCIe ile bağlandığında uç nokta, belleğinin bir bölümünü kök tarafa bir adres penceresi (BAR) olarak açar. Kök taraftaki sürücü bu pencereyi kendi adres uzayına eşler ve en basit aktarım, o eşlemeye yapılan bir memcpy'dir. Çalışır, ama her bayt işlemciden geçer: işlemci veriyi okur, pencereye yazar, denetleyici bunu sırayla paketlere (TLP) çevirir. Kopya sürerken o çekirdek meşguldür ve hız, hattın değil bu döngünün hızıdır.

DMA'da iş bölümü değişir. İşlemci denetleyiciye kaynak adresi, hedef adresi ve boyutu verir; veriyi bellekten alıp hatta süren, denetleyicinin içindeki DMA motorudur. Bizim kurulumumuzda bu motor uç noktada, yani Orin'in PCIe denetleyicisinde. Linux çekirdeği bu tür denetleyici için hazır bir sürücü taşıyor (dw-edma; Kconfig açıklaması "normally implemented on endpoints SoCs" diyor). Jacinto tarafının PCIe denetleyicisi ise farklı bir çekirdek ailesinden (Cadence); iki tarafın aynı donanım olduğunu varsaymak ilk tuzaktır.

Çekirdek belgeleri farkı açıkça söylüyor. NVMe uç nokta sürücüsünün belgesinde şu cümle var: DMA desteklenmiyorsa MMIO kullanılır ve bu "kötü performansla sonuçlanır". Aynı sürücünün yama mektubunda, DMA'lı bir RK3588 kartında 512 KB'lik rastgele okumada 2,82 GB/s raporlanıyor. Bizim ölçümümüz farklı kartlarda ve farklı bir iş yükünde; sayıları yan yana koymak için değil, büyüklük mertebesinin tek başına bize ait olmadığını göstermek için anıyoruz.

Hattın tavanı ne, bize ne kadarı kalıyor?

PCIe 3.0 şerit başına 8 GT/s taşır ve 128b/130b kodlama kullanır. Dört şerit için hesap:

4 şerit × 8 Gbit/s × 128/130 ÷ 8 = 3,94 GB/s      (yön başına, ham)

Bu tavana hiçbir aktarım ulaşmaz, çünkü veri paketlenir. Her paketin başlığı, sıra numarası ve hata denetimi vardır; Xilinx'in WP350 notu bu ek yükü 20–30 bayt olarak veriyor. Paketin taşıyabileceği en büyük veri (Max_Payload_Size) ise iki ucun anlaştığı bir değerdir: 128 bayttan 4096 bayta kadar tanımlıdır ve hattaki her cihaz aynı değeri kullanmak zorundadır.

Azami yük Paket verimi (WP350, 20 bayt ek yük) 3,94 GB/s tavanından kalan
128 bayt %86 yaklaşık 3,4 GB/s
256 bayt %92 yaklaşık 3,6 GB/s
512 bayt %96 yaklaşık 3,8 GB/s

Son sütun bizim çarpımımızdır, ölçüm değildir; Gen3 çerçevelemesinde ek yük 20 bayttan biraz fazladır ve akış denetimi paketleri de hattı kullanır. Bizim kartlarımız açılışta 128 baytta anlaşıyordu; ikisi de 256 baytı desteklediği için değeri yükselttik. Ölçtüğümüz 3,0–3,2 GB/s, ham tavanın %76–81'ine denk geliyor.

Bir de birim tuzağı var. Bazı sınama araçları 2²⁰ baytı "MB" diye yazar. GB ölçeğinde fark %7'dir (2³⁰ / 10⁹ = 1,074); aracın hangi birimi bastığını bilmeden iki ölçümü karşılaştırmayın.

DMA'nın bedeli: küçük aktarımlar

DMA bedava değildir. Her aktarım için bir komut hazırlanır, adresler yazılır, bitince bir kesme gelir. Bu hazırlık sabit bir süredir ve aktarım küçüldükçe toplamın içindeki payı büyür. Bizim ölçümlerimizde birkaç kilobaytlık aktarımlarda işlemci kopyası DMA'nın önüne geçebiliyor; megabaytlar düzeyinde ise DMA açık farkla hızlı.

Bundan iki pratik sonuç çıkar. Birincisi iş bölümü: kontrol bayrakları ve küçük parametreler işlemciyle, kare gibi büyük yükler DMA ile gider. İkincisi dürüstlük: "3 GB/s ise 3 MB'lik kare 1 ms'de gider" hesabı yanlıştır, çünkü sabit hazırlık süresini yok sayar. Kare başına süreyi bant genişliğinden bölerek değil, o boyuttaki aktarımı ölçerek bulmak gerekir. Biz bu yüzden görüntüde milisaniye yazmadık.

Bellek türü: önbellekli mi, write-combining mi?

Paylaşılan belleğin nasıl eşlendiği, yerel erişim hızını doğrudan belirler. Çekirdeğin aygıt G/Ç belgesi iki uç durumu tarif ediyor: ioremap() önbelleği atlar ve her erişimi ayrı ayrı aygıta gönderir; ioremap_wc() yazmaları birleştirmeye izin verir ve belgenin deyişiyle genellikle video çerçeve belleklerinde, yazma başarımını artırmak için kullanılır. Normal önbellekli bellek ise okuma ve karşılaştırmada çok daha hızlıdır, ama bir şartı vardır: karşı taraf o belleğe DMA ile yazdığında işlemcinin önbelleği eski veriyi tutuyor olmamalıdır.

Tutarlılığı donanım garanti ediyorsa (denetleyici, işlemci önbelleğiyle tutarlı bir ara bağlantının üzerindeyse) önbellekli eşleme güvenlidir. Garanti edemiyorsa ya her aktarımda önbelleği boşaltırsınız, ki bu işlemci zamanı yer, ya da write-combining'de kalırsınız. Biz iki tarafta farklı seçim yaptık: tutarlılığı doğrulayabildiğimiz tarafta önbellekli, diğerinde write-combining. Kural basit: önce doğruluk sınanır (rastgele veri, rastgele adres, karşılaştırma), hız ondan sonra ölçülür.

"Kare indi" haberini kim verir?

Uç noktanın kök tarafa haber vermesi standarttır: çekirdeğin uç nokta çatısı bunun için pci_epc_raise_irq() işlevini sunar ve MSI ya da MSI-X üretir. Ters yön öyle değildir. Kök tarafın uç noktaya "yeni iş var" demesi için PCIe'de hazır bir kesme yolu yoktur; Linux'a bu yönde bir "doorbell" desteği ancak 6.17 sürümünde ve belirli donanım koşullarıyla girdi. Çekirdekteki NVMe uç nokta sürücüsü bile kuyrukları sürekli yoklayarak çalışıyor.

Yoklama iki şeyden birini harcar: ya bir çekirdeği ya da tepki süresini. Biz iki yönde de kesme kullanıyoruz; görüntüdeki "her Orin kare indiği anda başlar" cümlesinin dayanağı budur. Bunun dört birimli bir hatta nasıl ölçekleneceğini ölçmedik.

"Doğrudan GPU belleğine" ne demek?

Zero-copy, verinin hiç taşınmadığı anlamına gelmez: kare hattan bir kez geçer. Kastedilen, o geçişin öncesinde ve sonrasında işlemcinin kareyi bir tampondan ötekine kopyalamamasıdır. Orin'de bunu mümkün kılan iki şey var. Aktarım için ayrılan bellek fiziksel olarak sabit ve bitişiktir; amaç, GPU gibi birimlerin aynı bölgeye erişebilmesidir. Ve NVIDIA'nın "CUDA for Tegra" belgesinin söylediği gibi, Tegra'da aygıt belleği ile ana bellek aynı fiziksel DRAM'dedir, bu yüzden yinelenen bellek ayırma ve veri aktarımından kaçınılabilir.

Bu yazı, o bölgenin GPU tarafında nasıl eşlendiğinin ayrıntısına girmiyor. Jetson'da çıkarım hattının geri kalanını NVIDIA Jetson sayfamızda, Jacinto tarafını Texas Instruments sayfamızda anlatıyoruz.

Operatöre giden son adım

Kare işlendikten sonra operatörün ekranına WebRTC ile gider; WebRTC, tarayıcıda gerçek zamanlı medya için W3C ve IETF'in tanımladığı protokol ailesidir. Bu adımın gecikmesi PCIe'den bağımsızdır: kodlama, ağ ve tarayıcının tamponu belirler. Yöntemini düşük gecikmeli video notumuzda anlattık; burada ölçüm vermiyoruz.

Nerede yanlış gider

  1. Bant genişliğini gecikme sanmak. Büyük aktarımdaki GB/s, küçük aktarımın süresini söylemez; sabit hazırlık süresi baskın çıkar.
  2. Varsayılan paket boyutunda kalmak. İki uç daha büyüğünü desteklese de açılışta küçük değerde anlaşabilir. Anlaşılan değeri okuyun.
  3. Hızlı ama bayat veri. Önbellekli eşleme karşılaştırma sınamasında hızlı görünür; karşı tarafın yazdığı veriyi görmüyorsa sonuç yanlıştır. Sınama verisi rastgele olmalı, her turda bellek sıfırlanmalıdır.
  4. Ayrılmış belleklerin çakışması. Aktarım belleği aygıt ağacında elle ayrılır. Başka bir birimin bölgesiyle çakışırsa çekirdek yalnızca açılışta uyarır; sonrası sessiz veri bozulmasıdır.
  5. DMA'yı her durumda hızlı ve her işte hazır saymak. Küçük aktarımda sabit hazırlık süresi baskındır ve her DMA motoru her işlemi desteklemez: çekirdeğin kendi sınama rehberi, DMA'lı kopyalama sınamasının DMA'lı denetleyicilerin çoğunda başarısız olacağını yazar. Oranı kendi kartınızda ölçün.

Bu yazının söyleyemedikleri

Ölçtüğümüz iki şey var: iki kart arasında DMA ile 3,0–3,2 GB/s ve 128 MB'lik aktarımlarda DMA'nın işlemci kopyasına yaklaşık 8 kat üstünlüğü. İki hız değerinin hangi yöne ait olduğunu ayrı kaydetmedik, bu yüzden aralık olarak yazıyoruz. 8 kat oranı önceki bir ölçüm turundan geliyor; güncel DMA hızıyla yeniden ölçülmedi.

Ölçmediklerimiz: dört Orin'li hattın uçtan uca gecikmesi, tek bir karenin kameradan operatöre süresi, yük altında kesme gecikmesi ve uzun süreli çalışmada kararlılık. Cevap için şunları ölçerdik:

  • Kare boyutunda aktarım süresi: ortalama değil, p99 ve en kötü değer, gerçek kare boyutlarıyla.
  • Kesmeden işe başlama süresi: kare indiği andan GPU işinin başladığı ana, donanım zaman damgasıyla.
  • Zincirin toplamı: birim sayısı arttıkça gecikmenin nasıl büyüdüğü.
  • Cam-cam gecikme: kameranın gördüğü olaydan operatör ekranındaki piksele kadar.

Bu tür bir hattı kendi kartlarınızda kurmak, kenarda yapay zekâ hattı işinin sürücü katmanıdır.

Sık sorulan sorular

Zero-copy PCIe ne demek?

Karenin iki kart arasında hattan bir kez geçmesi, bunun öncesinde ve sonrasında işlemcinin onu bir tampondan ötekine kopyalamaması demektir. Veriyi denetleyicinin DMA motoru taşır; işlemci yalnızca aktarımı tarif eder.

PCIe Gen3 ×4 hattından en fazla ne kadar veri geçer?

Ham tavan yön başına 3,94 GB/s'dir (4 şerit × 8 Gbit/s × 128/130). Paket başlıkları ve akış denetimi bunun bir kısmını alır; azami yük boyutu büyüdükçe kayıp azalır. Tezgâhımızda DMA ile 3,0–3,2 GB/s ölçtük.

DMA her zaman işlemci kopyasından hızlı mıdır?

Hayır. DMA'nın her aktarımda sabit bir hazırlık bedeli vardır; birkaç kilobaytlık aktarımda işlemci kopyası öne geçebilir. Megabaytlar düzeyinde DMA açık farkla hızlıdır: bizim hattımızda 128 MB'lik aktarımlarda yaklaşık 8 kat.

Bant genişliğinden kare başına gecikme hesaplanır mı?

Hesaplanmamalı. Bölme işlemi sabit hazırlık süresini, kesme gecikmesini ve zincirdeki diğer adımları yok sayar. Kare boyutundaki aktarımı doğrudan ölçmek gerekir.

Kaynaklar

Erişim tarihi: 1 Ekim 2026.