- recall, yüzlerce şirkete toplantı botları sunan ve AWS üzerinde büyük ölçekli altyapı işleten bir hizmet
- Maliyet açısından verimli bir hizmet sunmak için donanım performansını mümkün olan en üst düzeyde kullanmaya çalışıyorlar
- Son birkaç yılda bulut sağlayıcılarının GPU erişilebilirliği istikrarsız olduğundan, video işlemeyi GPU yerine CPU üzerinde gerçekleştirdiler
- Headless Chromium kullanan botların profili çıkarıldığında, CPU süresinin büyük kısmının video işleme (encode/decode) yerine
__memmove_avx_unaligned_erms ve __memcpy_avx_unaligned_erms bellek kopyalama işlevlerinde harcandığı görüldü
memmove ve memcpy, C standart kütüphanesindeki (glibc) bellek bloklarını kopyalama işlevleridir
memmove, çakışan bellek aralıklarının kopyalanmasıyla ilgili bazı istisna durumlarını ele alır; ancak her iki işlev de "bellek kopyalama" işlevi olarak sınıflandırılabilir
avx_unaligned_erms son eki, Advanced Vector Extensions (AVX) destekleyen sistemler için optimize edildiğini ve hizalanmamış bellek erişimine de uygun olduğunu gösterir
erms, Enhanced REP MOVSB/STOSB anlamına gelir; modern Intel işlemcilerde hızlı bellek taşıma için yapılan bir optimizasyondur. Bunu "belirli işlemciler için daha hızlı bir uygulama" olarak düşünebilirsiniz
- Profil çıkarma sonucunda, bu işlevleri en çok çağıranın veri alan Python WebSocket istemcisi olduğu görüldü
- Sonraki sırada ise veri gönderen Chromium’un WebSocket implementasyonu yer aldı
WebSocket’in sorunları
- Ham video verisini Chromium’un JS ortamından encoder’a aktarmak için yerel bir WebSocket sunucusu kullanıldı
- Ham 1080p 30fps video akışı, saniyede 93 MB’tan fazla yüksek bant genişliği gerektiriyordu
- WebSocket kullanımı yüksek hesaplama maliyetine yol açtı; bunun başlıca nedenleri parçalama (fragmentation) ve maskeleme (masking) idi
- Parçalama: Chromium’un WebSocket implementasyonu 131 KB üzerindeki mesajları birden çok frame’e bölüyor. 3 MB’tan büyük ham video frame’leri 24’ten fazla ayrı frame olarak iletiliyordu
- Maskeleme: Güvenlik nedeniyle WebSocket, istemciden sunucuya gönderilen tüm frame’leri maskeler. Saniyede 100 MB’ı aşan büyük hacimli veride bu anlamlı bir ek yük oluşturuyordu
Alternatif arayışı
- Tarayıcı API’leriyle WebSocket’ten çok daha yüksek performanslı bir şey kurmak zor olduğundan, özel işlevsellik eklemek için Chromium’u fork etmeye karar verdiler
- Üç alternatif değerlendirildi: raw TCP/IP, Unix Domain Socket, Shared Memory
- TCP/IP: WebSocket’in parçalama/maskeleme sorunlarından kaçınılabilir, ancak azami paket boyutu küçük olduğundan parçalama sorunu yine sürer. Ayrıca kernel alanına kopyalama ek yükü vardır
- Unix Domain Socket: Ağ yığınını tamamen atlayabilir, ancak kullanıcı alanı ile kernel alanı arasında yine veri kopyalamak gerekir
- Shared Memory: Birden çok sürecin aynı anda erişebildiği bellek. Arada kopyalama olmadan Chromium doğrudan paylaşılan belleğe yazar ve encoder veriyi hemen okuyabilir
Paylaşılan bellek tabanlı aktarımın uygulanması
- Veriyi paylaşılan bellekte art arda okuyup yazmak için ring buffer biçiminde bir yapı uygulandı
- Gereksinimler: lock-free, çoklu üretici/tek tüketici, değişken frame boyutu, zero-copy okuma, sandbox uyumluluğu, düşük gecikmeli sinyalleme
- Hazır ring buffer implementasyonları değerlendirildi, ancak tüm gereksinimleri karşılayan bir çözüm olmadığından bunu doğrudan kendileri geliştirdiler
- Zero-copy okumayı desteklemek için işaretçiler
write, peek, read olmak üzere üçe ayrıldı
- Thread safety için atomik işlemler kullanıldı ve yeni veri oluştuğunu / alan açıldığını bildirmek için named semaphore kullanıldı
- Paylaşılan bellek tabanlı ring buffer implementasyonu ve diğer optimizasyonlar sayesinde botların CPU kullanımını %50’ye kadar azaltabildiler. Sonuçta AWS maliyetlerinde yıllık 1 milyon dolardan fazla tasarruf sağlandı.
3 yorum
Hacker News yorumu
Bu, bir startup'ın "yeterince iyi" bir kestirme yolu seçip daha sonra optimize etmesinin tipik bir hikayesi.
Ham video verisinin gerektirdiği yüksek bant genişliğinin şaşırtıcı olduğu yönünde bir görüş var.
Sorunun AWS değil, CPU döngülerinin boşa harcanması olduğu yönünde bir görüş var.
TCP/IP ağlarındaki MTU ve MSS değerlerinin video kare boyutlarına kıyasla küçük olduğuna dikkat çekiliyor.
Chromium'un Mojo'su kullanılırsa platforma özgü kodlar konusunda endişelenmeye gerek olmadığı yönünde bir görüş var.
Sorunun ağ değil, video codec'leri hakkındaki anlayış eksikliği olduğu yönünde bir görüş var.
Şeffaflık övülüyor ve ürün fiyatlandırmasında da şeffaflık istendiği belirtiliyor.
WebSocket protokolündeki masking'in ortadaki adam sorununu çözmeye yönelik bir girişim olduğu açıklanıyor.
Video verisinin sıkıştırılmadan aktarılmasının garip olduğu belirtiliyor.
Ham videonun başlangıçta WebSocket üzerinden aktarılması yaklaşımının şaşırtıcı olduğu söyleniyor.
En baştan yanlış geliştirmişler zaten..
"Ham videoyu WebSocket ile iletmeye yönelik ilk yaklaşımın şaşırtıcı olduğu söyleniyor." Bu görüşe katılıyorum.