Blog

CPU çevrimi başına aktarım hızı: bir yönlendiriciyle karşılaşmayı atlatan sayı

Bir laboratuvar sayısı ile bir donanım sayısı neredeyse hiç uyuşmaz. İkisini de ölçtük, aralıkları koruduk, bir kez yanlış sonuç üreten tuzağı açıkladık ve nerede kaybettiğimizi açıkça söyledik.

6 Eylül 2026 tarihinde yayımlandı

İki fiziksel yönlendiricide, gerçek bir gigabit LAN üzerinden gerçek trafik taşırken, tünel çekirdeğimiz 122 Mbit/s ile itti; yönlendiricinin kendi çekirdek tünel uygulaması ise 66.8 Mbit/s ile — aynı gönderici üzerinde, Mbit başına daha az CPU ile. Hiçbir rakam tek başına hikâyenin tamamı değildir: iki kolun farklı trafik üreticileri kullanması gerekti, çünkü tek bir üretici bu karşılaştırmanın iki tarafında da çalışmaz. Bu yüzden tartışılacak oran, her kolun kendi tünelsiz tavanına karşı olan oranıdır; bu, aşağıdaki tabloda yer alır ve bizi daha da lehimize çevirir, aleyhimize değil. Bir dizüstü bilgisayarda dört VM'lik bir laboratuvar çalıştırması, mutlak rakamlarla daha hızlı bir şey ve bir eksende daha az göz alıcı bir şey söylüyor. Yönlendirici rakamına daha çok güveniyoruz, çünkü ikisinden yalnızca yönlendirici, bir müşterinin trafiğinin fiilen geçtiği yerdir.

Öne çıkarılmaya değer bulgu budur ve bu yazının bir yerine iki sonuç bölümü olmasının da nedeni budur: laboratuvar ile donanım, hangi eksenin önemli olduğu konusunda anlaşmıyor ve bu anlaşmazlığın üzerini örtmek, her iki rakamın kazandırdığından daha fazla güvenilirliğe mal olurdu.

Rakamlardan önce bunu okuyun. Veri düzlemimiz varsayılan olarak tek iş parçacığı kullanır. Laboratuvarda yanında çalıştırdığımız karşılaştırma öğesi ise varsayılan olarak dört kullanır. Eşitlenmeden bırakıldığında, yalnızca bu bayrak aktarım hızını ~789'dan 1427 Mbit/s'ye kadar sallar — bu bir varsayılan farkıdır, veri yolu farkı değil — ve burada zaten bir kez yanlış yayımlanmış rakama yol açtı. Aşağıdaki her laboratuvar rakamı, her iki Rust çekirdeğini de tek iş parçacığına sabitler. Bu tablodaki Go ve çekirdek uygulamaları kendi varsayılanlarında çalıştı; bunlar birden fazla iş parçacığı kullanır — bu da bir şey değiştirirse onları tek iş parçacığımıza karşı avantajlı gösterir. Teslim edildiği haliyle varsayılan fark, göz ardı edilerek gizlenmesin diye ayrıca, bir kez gösterilir.

Neyin, ne üzerinde ölçüldüğü

İki bağımsız ortam, çünkü bir kıyaslama yalnızca çalıştığı ortam içinde dürüsttür — bir iperf3 rakamı ile bir bandwidth-test rakamı, iki isim taşıyan tek bir rakam değildir ve bir dizüstü bilgisayarın çekirdeklerini paylaşan bir VM bir yönlendirici değildir.

Donanım — iki MikroTik yönlendirici, bir gigabit LAN, 2026-09-01. Gönderici olarak RB3011UiAS (ARMv7, 2×1400 MHz), alıcı olarak cAP ax (ARM64, 4×864 MHz), ikisinde de RouterOS 7.24.1. Çekirdeğimiz, bir RouterOS konteynerinde, kullanıcı alanında, fv olarak, yönlendiricinin kendi çekirdek içi WireGuard protokolü uygulamasına karşı çalıştı — bu donanımda mevcut olan tek elma-elma karşılaştırması, çünkü RouterOS'un kendisinde sunulan tek alternatif budur. İki üretici, çünkü hiçbiri uygulamaları temiz biçimde geçmez: konteyner çalıştırmamız için dd | nc, çekirdek çalıştırması için RouterOS'un kendi bandwidth-test'i — her biri kontrol olarak kendi tünelsiz tavanını taşır, böylece okuyucu orana güvenmeden önce tavanı akıl kontrolünden geçirebilir.

Laboratuvar — bir Apple silikon anamakine üzerinde QEMU/HVF altında dört aarch64 Debian konuğu, 2026-08-31. Test edilen her ikili arasında aynı anahtar çiftleri, adresler, portlar, MTU ve arayüz açılışı: çekirdeğimiz, çekirdeğimizin çatallandığı kullanıcı alanı çekirdeği olan boringtun 0.7, wireguard-go (WireGuard protokolünün referans uygulaması, kullanıcı alanı) ve Linux çekirdeğinin kendi WireGuard protokolü modülü. 15 saniyelik iperf3 çalıştırmaları, her birinden üç örnek, yukarıdaki uyarı kutusundaki nedenden dolayı her iki Rust çekirdeği de tek bir veri düzlemi iş parçacığına sabitlendi.

task test:impls    # lab: ours vs boringtun vs wireguard-go vs the kernel
task test:all      # lab: single-hop, multi-hop, and the comparison

Yönlendirici çalıştırması henüz bir task hedefi değildir — her kutuda RouterOS'un yerleşik WireGuard protokolü sunucusuna karşı, bir RouterOS konteynerinde elle başlatılan fv'dir. Tam topoloji ve her ham satır kendi docs/benchmarks/results.csv dosyamızda yer alır.

Önemli olan sayı: yönlendiricide

Ölçütçekirdeğimiz (kullanıcı alanı)yönlendiricinin kendi çekirdek tüneli
aktarım hızı122 Mbit/s66.8 Mbit/s
CPU, gönderici65% (63–67)74% (70–79)
CPU, alıcı18% (10–22)20% (18–21)
Mbit başına CPU0.53 %/Mbit1.10 %/Mbit
RTT1.22 ms0.92 ms
yerleşik bellek (gönderici / alıcı)3.0 / 3.1 MBçekirdek içi, ayrıştırılamaz
üreticidd | ncbandwidth-test
o üreticinin tünelsiz tavanı187 Mbit/s220.5 Mbit/s
kendi tavanına karşı korunan65%30%
çekirdeğimiz122 Mbit/syönlendiricinin çekirdek tüneli66.8 Mbit/s

Çubuk uzunluğu ∝ Mbit/s, eksen 0–140. Her iki çalıştırmada da aynı RB3011 göndericisi; baştan sona CPU tavanı odur, alıcı cAP ax neredeyse %20'de boşta beklerken %65–79 arasında.

İki bağımsız çerçeveleme birbirini doğruluyor; bu da sonucu seçilerek değil inandırıcı kılan şeydir: mutlak aktarım hızı çekirdeğimizi 1.8× lehine çeviriyor, her üreticinin kendi tartışmasız tavanına karşı korunan aktarım hızı ise onu 2.2× lehine çeviriyor. Tablonun söylemediği şey: iki üretici aynı araç değildir, bu yüzden tek bir manşet oranı yerine her iki tünelsiz tavan da yazdırılmıştır ve gönderici trafiği yerel olarak üretmek yerine gerçek ağ trafiği alsaydı her iki rakam da değişirdi. Aşağıdaki laboratuvar tablosunun aksine, bunlar tekil çalıştırmalardır: köşeli parantez içindeki yüzdeler, o çalıştırma sırasında CPU'nun dolaştığı aralıktır, tekrarlanan denemeler arasındaki bir yayılma değildir.

Laboratuvar: üç kullanıcı alanı çekirdeği, bir çekirdek, eşitlenmiş iş parçacıkları

çekirdektürTCP Mbit/s (aralık, n=3)zirve bellekp99 gecikme
bizimki, 1 iş parçacığıkullanıcı alanı, Rust1535 (1506–1554)3.5 MB0.94 ms
boringtun, 1 iş parçacığıkullanıcı alanı, Rust1427 (1346–1479)5.3 MB1.15 ms
wireguard-go, varsayılankullanıcı alanı, Go1228 (1221–1239)34.8 MB1.39 ms
çekirdek WireGuard, varsayılançekirdek, C1376 (1366–1386)— (çekirdek, ayrıştırılamaz)0.96 ms

Teslim edildiği haliyle, eşitlenmemiş: çekirdeğimiz varsayılan olarak 1 iş parçacığı kullanır ve 1535 Mbit/s çalıştı; boringtun varsayılan olarak 4 iş parçacığı kullanır ve bu ayarda ~789 Mbit/s çalıştı. Yalnızca varsayılana karşı varsayılan rakamını bildirmek, aynı hatayı göz alıcı yönde tekrarlardı. Her iki rakam da gerçektir; yalnızca biri veri yolunu iş parçacığı sayısından ayırır.

CPU maliyeti, laboratuvarın bu yazıdaki yerini hak ettiği noktadır — bu, yönlendirici tablosunun gösteremediği tek eksendir, çünkü bir yönlendiricinin çekirdek içi karşılaştırma öğesi, karşılaştıracak bir CPU dökümü vermez.

kullanıcısistemçekirdeğimiz0.90 s/Gbit toplamkullanıcı 0.347 · sistem 0.549 s/Gbitboringtun1.08 s/Gbit toplamkullanıcı 0.290 · sistem 0.787 s/Gbitwireguard-go2.37 s/Gbit toplamkullanıcı 0.876 · sistem 1.490 s/Gbit

Düşük olması daha iyidir. Eksen 0–2.5 s/Gbit, doğrusal. Her iki bölüm de soldan sağa yığılır; bölünme, bir sonraki bölümün kaybının göründüğü yerdir.

çekirdeğimiz3.5 MBboringtun5.3 MBwireguard-go34.8 MB

Logaritmik ölçek, 1–50 MB, belirtiliyor çünkü dürüst varsayılan bu değildir: doğrusal bir eksende wireguard-go'nun 34.8 MB'ı diğer iki çubuğu ince bir çizgiye düzleştirirdi.

Kazanmadığımız yerler

İki yer, ikisi de CSV'nin içine gömülmek yerine açıklanıyor:

Laboratuvarda kullanıcı modu CPU'su. Daha ucuz Rust karşılaştırma öğesinin 0.290'ına karşı 0.347 s/Gbit — o tabloda önümüzde olduğu tek sütun. Bizim okumamız, bunun israf değil satın alınmış olduğudur: çekirdeğimiz her iki yönde de TUN sağlama toplamı boşaltması (checksum offload) yapar; bu da işi çekirdekten alıp kullanıcı zamanı olarak sayılan kullanıcı alanı CPU'suna taşır — ve bu değiş tokuşun geri ödendiği sistem-CPU sütunu rahatça önde (0.549'a karşı 0.787). Toplam CPU yine de kazanıyor. Yukarıdaki kullanıcı/sistem bölünmesi, özellikle bu değiş tokuşun ileri sürülmek yerine görünür olması için gösteriliyor.

Yönlendiricide gidiş-dönüş süresi. Çekirdek tünelinin 0.92 ms'ine karşı 1.22 ms — çekirdek içi çözümün açıkça kazandığı tek donanım ekseni; bunun sıradan nedeni, bizim yolumuzun bir konteynerin veth sıçramasına ve çekirdek içi bir yolun ödemediği bir kullanıcı alanı zamanlama dönüşüne mal olmasıdır. İlginç biçimde laboratuvar, p99 gecikmesinde tersi bir sıralama gösteriyor (çekirdeğin 0.96 ms'ine karşı 0.94 ms) — bunun ötesinde “farklı ortamlar, farklı darboğazlar” dışında bir anlam çıkarmıyoruz ve hangi rakam daha göz alıcıysa onu seçmek yerine bunu söylüyoruz.

Neyin taze, neyin devralınmış olduğu

Yukarıdaki her rakam bir tarih taşır ve tarihler önemlidir: yönlendirici tablosu 2026-09-01, laboratuvar tablosu 2026-08-31'dir. O zamandan beri, koordineli bir major-sürüm sıçraması, veri düzlemimizin her pakette çağırdığı temel kripto crate'lerini taşıdı — chacha20poly1305, blake2, curve25519-dalek — ve o ağaca karşı tam laboratuvar veya yönlendirici karşılaştırmasını yeniden çalıştırmadık. Yukarıdaki rakamlar gerçektir ve dikkatle ölçülmüştür, ama yayımlandığı tarih itibarıyla altı gün eskidir, bu sıçramadan önceki bir ağaç üzerindedir. Bunları sessizce değil, bunu belirterek yayımlıyoruz ve elimize geçtiğinde bir yeniden çalıştırmayı tarihleyeceğiz. Yönlendirici rakamı da kendi kayıtlarımızda belirli bir commit'e sabitlenmiş değildir — “2026-09-01”i bir optimizasyon değişikliğine bağlı olarak değil, “eylül başı” olarak okuyun.

Bugün, bu makinede, bir yönlendirici veya VM laboratuvarı olmadan yeniden çalıştırabileceğimiz şey, kripto sıçramasının en doğrudan dokunduğu yoldaki kısımdır: yukarıdaki her soket, TUN ve iş parçacığı kaygısından yalıtılmış encapsulate ve decapsulate maliyeti.

işlem, paket boyutuçekirdeğimizboringtun 0.7.1
kapsülleme, 64 B219.2 ns218.7 ns
kapsülleme, 512 B436.4 ns442.5 ns
kapsülleme, 1420 B938.1 ns968.3 ns
kapsül açma, 64 B238.8 ns226.7 ns
kapsül açma, 512 B562.1 ns539.2 ns
kapsül açma, 1420 B1099.5 ns1069.4 ns

2026-09-05'te, Apple M3 Max üzerinde, cargo bench -p forestvpn-quantum --bench datapath_benches -- --measurement-time 3 --warm-up-time 1 ile, criterion 0.8.2, nokta başına 100 örnekle yeniden çalıştırıldı. Soket yok, TUN yok, iş parçacığı yok — tamamlanmış tek bir el sıkışma, ardından döngü içinde kapsülleme/kapsül açma. Sonuçlar yöne ve paket boyutuna göre karışıktır, her iki yönde de birkaç yüzde içindedir; tam olarak beklediğimiz şey de budur: çekirdeğimiz bu yolu üst akışından çatalladı ve ikisi de artık aynı RustCrypto ilkel nesneleri kuşağı üzerinde duruyor. Bu bir aktarım hızı iddiası değildir — çatallanmış kripto yolunun kendisinin, gürültü payı içinde, üst akışınkiyle yaklaşık aynı maliyete sahip olduğunu söyler; bu da yukarıdaki laboratuvar ve yönlendirici kazanımlarını güvenilir kılan şeydir: bunlar yığının başka bir yerinden gelir (syscall toplu işleme, boşaltma, iş parçacığı), daha hızlı bir şifreleyiciden değil.

Yeniden üretme

task test:impls          # lab: ours vs boringtun vs wireguard-go vs the kernel
task test:all            # lab: single-hop, multi-hop, and the multihop cost table
cargo bench -p forestvpn-quantum --bench datapath_benches -- --measurement-time 3 --warm-up-time 1

Yönlendirici çalıştırması bugün elle yapılır: her kutuda bir RouterOS konteynerinde fv, RouterOS'un kendi WireGuard protokolü sunucusuna karşı.

Bunun size ne kazandırdığı konusunda dürüst olmak gerekirse: düzenek ve buradaki her tablonun arkasındaki ham results.csv, bugün herkese açık olmayan kendi ağacımızda yaşıyor. Yukarıdaki komutları, klonlayıp tekrarlayabileceğiniz bir şey olarak değil, çalıştırdığımızın tam bir ifadesi olarak okuyun. Bize en az bağımlı olan iddia, kontrol etmeye en çok değer olandır da — boringtun ve wireguard-go herkese açıktır, iperf3 herkese açıktır ve bu yazının başındaki iş parçacığı sayısı tuzağı (tek bir bayrağın bir karşılaştırma öğesini tek bir makinede kabaca 789 ile 1427 Mbit/s arasında oynatması) bu üçüne sahip ve döngüde bizim kodumuz olmayan herkes tarafından yeniden üretilebilir. Sizde de doğrulanırsa, tartışılacak satırlar yukarıdaki eşitlenmiş satırlardır. Doğrulanmazsa, bunu duymak isteriz.

Tüm yazılar

Türkçe
Bize her şeyi sorun