Hazırlık ve Tamamlama Zaman Uyumsuz GÇ Bellek kullanımı?


12

Rust'da Async IO'nun uygulanmasıyla ilgili bu konuşmayı izliyordum ve Carl iki potansiyel modelden bahsediyor. Hazırlık ve Tamamlama.

Hazırlık Modeli:

  • bir soketten okumak istediğiniz çekirdeğe söylersiniz
  • bir süre başka şeyler yap…
  • çekirdek soketin ne zaman hazır olduğunu size söyler
  • okudun (bir tampon doldur)
  • ne istersen yap
  • arabelleği boşalt (Rust ile otomatik olarak gerçekleşir)

Tamamlanma Modeli:

  • çekirdeğin doldurması için bir tampon ayırırsınız
  • bir süre başka şeyler yap…
  • çekirdek tamponun ne zaman dolduğunu size söyler
  • verilerle ne gerekiyorsa yap
  • tamponu boşalt

Carl'ın hazır olma modelini kullanma örneğinde, hazır bir soketi doldurarak ve daha az bellek kullanmış gibi görünmesini sağlayan global bir tamponu serbest bırakabilirsiniz .

Şimdi benim varsayımlarım:

Bir soketin "hazır" olduğu söylendiğinde kaputun altında (çekirdek boşluğunda) veriler zaten mevcuttur. Ağ üzerinden (veya her yerden) sokete girdi ve işletim sistemi verileri tutuyor.

Bu hafıza tahsisi sihirli bir şekilde hazır olma modelinde olmaz gibi değil. Sadece işletim sistemi onu sizden soyutlıyor. Tamamlama modelinde, işletim sistemi sizden veri akmadan önce bellek ayırmanızı istiyor ve ne olduğu belli.

İşte Hazırlık Modelinin değiştirilmiş versiyonum:

  • bir soketten okumak istediğiniz çekirdeğe söylersiniz
  • bir süre başka şeyler yap…
  • DEĞİŞİKLİK: veriler işletim sistemine gelir (çekirdek belleğinde bir yer)
  • çekirdek soketin hazır olduğunu söyler
  • okudunuz (yukarıdaki çekirdek arabelleğinden ayrı bir tampon daha doldurun (ya da bir işaretçi mi aldınız?))
  • ne istersen yap
  • arabelleği boşalt (Rust ile otomatik olarak gerçekleşir)

/ Varsayımlarım

Kullanıcı-uzay programını küçük tutmaktan hoşlanıyorum ama gerçekte burada neler olduğu hakkında biraz açıklama yapmak istedim. Bir modelin doğal olarak daha az bellek kullanacağını veya daha yüksek bir eşzamanlı IO seviyesini destekleyeceğini görmüyorum. Düşüncelerini ve bunun daha derin bir açıklamasını duymak isterim.


Buraya YouTube konuşmasından da geldim. Nasıl IO zaman uyumsuz ya da nasıl olay döngüleri uygulamanın öğrenmeye herkes için Pas takımı "Aysnc Söyleşiler" bu çalma listesi vardır burada topluluk çok bilgili millet görüşme
cacoder

Yanıtlar:


5

Hazırlık Modeli'nde bellek tüketimi, uygulama tarafından kullanılmayan veri miktarı ile orantılıdır.

Tamamlama Modelinde bellek tüketimi, bekleyen soket çağrılarının miktarı ile orantılıdır.

Çoğunlukla boşta olan birçok soket varsa, Hazırlık Modeli daha az bellek tüketir.

Tamamlama Modeli için kolay bir düzeltme vardır: 1 baytlık bir okuma başlatın. Bu sadece küçük bir tampon tüketir. Okuma işlemi tamamlandığında, verilerin geri kalanını alan başka (belki de senkron) bir okuma okuyun.

Bazı dillerde Tamamlama Modelinin uygulanması son derece basittir. Bunun iyi bir varsayılan seçim olduğunu düşünüyorum.


1

Tamamlama modelinde, işletim sistemi sizden veri akmadan önce bellek ayırmanızı istiyor ve ne olduğu belli.

Ancak, alan ayırdığınızdan daha fazla veri girerse ne olur? Çekirdek, verileri düşürmemek için yine de kendi arabelleğini ayırmalıdır. (Örneğin, usr cevabında belirtilen 1 baytlık okuma hilesi bu yüzden çalışır.)

Bunun bir sonucu olarak, Tamamlama Modeli daha fazla bellek tüketirken, aynı zamanda (bazen) daha az kopyalama işlemi de yapabilir, çünkü arabelleğin etrafta tutulması, donanımın doğrudan DMA'nın dışına veya içine girebileceği anlamına gelir. Ben de şüpheli (ama ben daha az emin) Tamamlama Modeli Windows' IOCP için en az bir başka iş parçacığı üzerinde (olduğu durumda) gerçek kopyalama işlemi yapmak eğiliminde olduğunu ederken Modeli kapsamında öyle Hazırlık engellenmeyen read()veya write()aramak.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.