
Test yaması, Go'nun netip'inde IPv4'ten IPv6'ya dönüştürme sırasında bayt sıralamasını ortadan kaldırıyor
Test derleyicisi yeniden yazması, Go'nun netip.AddrFrom16(ip.As16()) örneğini dahili alanın doğrudan kopyalanmasına dönüştürüyor ve standart kütüphanenin 0,88 ns'lik çözümüyle aynı kısa assembly'yi üretiyor.
Dönüştürme örneği neden yavaş
Go'nun netip.Addr'i, IPv4 olarak eşlenen IPv6 adresinden açık bir IPv4 adresi döndüren Unmap() yöntemini sunar. Karşıt işlem için Map() veya To6() yöntemi mevcut değildir. Go bakımcıları bunun eklenmesini reddetti ve kullanıcıları netip.AddrFrom16(ip.As16())'e yönlendirdi, derleyicinin bunu optimize etmesi umuduyla.
Dahili olarak, netip.Addr IP adresini 128-bit değer olarak saklar ve aile ve bölgeyi şifrelemek için ek bir alan kullanır. To6()'nin standart kütüphane uygulaması, IPv4 adresleri için bu alanı değiştirebilirdi. Harici yardımcı ise tam tersine, adresi 16 baytlık bir diziye dönüştürmeli ve geri döndürmeliydi.
Benchmark sonuçları
Go 1.27.1 üzerinde Linux'ta ve AMD Ryzen 5 5600X 6 çekirdekli işlemcide yapılan benchmark'larda, standart kütüphanenin çözümü işlem başına 0,8775 ns sürdü. Güvenli yardımcı 7,137 ns sürdü, aynı dahili duruma vekil üzerinden erişen güvensiz uygulama ise 0,8682 ns. Bu nedenle yardımcı yaklaşık sekiz kat yavaştı.
Standart kütüphane ve güvensiz sürümlerin assembly'leri neredeyse birebir aynıydı. İkisi de adresin ailesini kontrol ediyor ve IPv4 işleme sırasında dahili aile değerini değiştiriyordu. Güvenli yardımcı, adresi 16 baytlık bir dizide düzenlediği, diziyi kopyaladığı ve yeniden çözdüğü için daha fazla talimat üretiyordu. Go 1.26.8 durumunda derleyici bu sıralamadan kaçınmıyordu.
Derleyici aşaması deneyi
Deney, netip.AddrFrom16(ip.As16()) örneğini derleyicinin noding aşamasında tam olarak yeniden yazar. Çağrıları, orijinal adresi kopyalayan ve IPv6 aile değerini atayan netip.Addr yapısıyla değiştirir. Yeniden yazma noding sırasında yapılmalıdır, çünkü daha erken tip kontrolü aşaması yapının dışa aktarılmamış alanlarına erişimi engeller.
Uyarlanmış derleme, yeniden yazma ile doğrudan uygulama gibi aynı kısa assembly'yi üretti ve testler net/netip ve yardımcı paket için başarıyla geçti. Analiz, Go bakımcılarının bu yaklaşıma pek olası olmadığını söylüyor, çünkü netip.Addr'in dahili düzenlemesine bağımlı ve noder'ın tip kontrollü sözdizimi ağacının sadık çevirisi üzerine daha fazla sorumluluk yüklüyor.
Önerilen SSA optimizasyonu
Daha genel bir yaklaşım, derleyicinin genel SSA aşamasını, özellikle memcombine geçişini hedefler. Önerilen yeniden yazma kuralları, yüklemeleri bellek taşımaları aracılığıyla yeniden adresler, saklanan değerleri sonraki yüklemeye kadar erteler ve bayt değiştirme işlemlerinin çiftlerini ortadan kaldırır.
Adresin her 64-bit yarısı için bu dönüşümler geçici diziyi, kopyasını ve fazladan bellek erişimini ortadan kaldırır. Üst yarının aktarımı ayrıca saklama işlemi aracılığıyla komşu, örtüşen adrese de mümkün. Sadeleştirmeden sonra her çıkış yarısı, karşılık gelen giriş yarısının kopyası haline gelir, bu da adres verilerini değiştirmeden bırakır ve gerekli aile değerini ayarlar.
SiTech — AI destekli web geliştirme
Hızlı ve modern web siteleri kuruyor, AI'yı gerçek iş akışlarına taşıyoruz. Projeniz veya sorunuz mu var? Yardımcı olmaktan mutluluk duyarız.