- The Art of Multiprocessor Programming ders kitabının futex kavramını ele almamasının üzücü olduğu yönünde bir itiraz dile getiriliyor
- Futex, modern paralel programlamada verimli senkronizasyonun temel bileşenlerinden biri ve eski System V tabanlı kilitlere göre daha yüksek performans sunuyor
- Futex, kilit edinme ile bekleme/uyandırma işlevlerini ayırarak gereksiz sistem çağrılarını ve ek yükü azaltan bir yapıya sahip
- Futex tabanlı olarak spinlock, mutex, özyinelemeli kilit gibi çeşitli eşzamanlılık primitiflerinin doğrudan nasıl uygulanacağına dair örnekler ve teknikler yer alıyor
- Yazar, kitabın gerçek mühendislik pratiği için zorunlu olan güncel senkronizasyon yöntemlerini ele almamasını, akademi ile sektör arasındaki kopukluğun bir göstergesi olarak görüyor
Giriş
- Phil Eaton, 'The Art of Multiprocessor Programming, 2nd Edition' için bir kitap kulübü başlattı
- Bu kitap paralel programlama alanında otoriter bir ders kitabı olarak görülse de yazar, içeriğin pratik faydadan yoksun olduğunu belirtiyor
- Özellikle, 4. sınıf lisans öğrencileri ve yüksek lisans öğrencilerine yönelik olduğu söylenmesine rağmen futex gibi temel bir senkronizasyon tekniğini ele almaması eleştiriliyor
Futex nedir – neden önemlidir
- Futex, “fast user space mutex” ifadesinin kısaltmasıdır; ancak gerçekte bir mutex'ten çok modern kilit uygulamaları için işletim sistemi destekli bir senkronizasyon ilkel bileşenidir
- Geçmişte kilitlerin çoğu System V IPC'nin semafor temelli yapısıyla uygulanıyordu ve bu da verimlilik ile ölçeklenebilirlik açısından sınırlamalar doğuruyordu
- Futex'in 2002'de Linux'a eklenmesiyle, 1000 eşzamanlı iş yükü ortamında System V kilitlerine kıyasla 20 ila 120 kat daha yüksek performans elde edildi
- Windows (2012) ve macOS (2016) gibi diğer işletim sistemleri de benzer mekanizmaları kullanıma aldı
- Günümüzde yaygın biçimde kullanılan pthreads gibi sistem kütüphanelerindeki kilitler futex kullanıyor
Futex'in çalışma mantığı ve farkı
- Geleneksel semaforlar kilitleme ile beklemeyi birleştirirken, futex kilit edinme ile bekleme/uyandırmayı ayırır
- Bu sayede gereksiz gecikmeler ve sistem çağrıları azaltılabilir; kilit bırakılırken bekleyen iş parçacığı olmadığı kesinse çekirdeğe girilmesine gerek kalmaz
- Futex'in wait çağrısı, “belirli bir bellek adresindeki değer istenen durumdaysa ancak o zaman bekleme” davranışı gösterir ve zaman aşımını da destekler
- Futex wake çağrısı, belirli bir bellek adresine bağlı iç bekleme listesinden istenen sayıda iş parçacığını uyandırır
- Bellek adresindeki gerçek değerin doğrulanmasını istemesi, durum zaten değişmişse gereksiz beklemeyi önler
Futex'in pratik kullanımı – doğrudan uygulama
- Futex düşük seviyeli bir ilkel olduğundan, derleyici ve donanımdaki bellek işlemi sıralaması sorunları dikkate alınarak
atomic veri türleri kullanılır
- Linux'ta futex sistem çağrısını
syscall ile doğrudan çağırmak gerekir; macOS'ta __ulock arayüzü kullanılır (yakın zamanda daha kolay API'ler de eklendi)
- Temel olarak futex wait başarılı olduğunda 0, başarısız olduğunda hata kodu (zaman aşımı vb.) döndürür
- Futex tabanlı temel işlemler:
h4x0r_futex_wait_timespec() : Beklenen değer eşleşiyorsa bekler, zaman aşımı uygulanabilir
h4x0r_futex_wake() : 1 ya da tüm bekleyenleri uyandırır
Mutex/spinlock/özyinelemeli kilit uygulamalarına dair pratik örnekler
Spinlock
- En basit kilit türüdür; yalnızca tek bir bit (
atomic_fetch_or) ile çalışır
- Kilidi alana kadar sonsuz döngüde (“spin”) bekler; ancak yüksek çekişme durumlarında CPU israfı, hatalı bırakma ve özyinelemeli çağrılarda deadlock riski gibi yapısal sorunlar vardır
Hibrit mutex (‘unsafe’ mutex)
- Genellikle önce spinlock ile denenir, belirli sayıda başarısızlıktan sonra verimli bloklama için futex'e geçilir
- Bekleyen yoksa gereksiz sistem çağrılarından kaçınılabilir ve bekleyenler için uyandırma sistem çağrıları en aza indirilebilir
- Sıkı sahiplik doğrulaması ya da özyineleme yönetimi eksik olduğundan “unsafe” adı kullanılır
Bekleyen sayaçlı mutex
- Bir bit kilit durumunu, geri kalan kısım ise bekleyenlerin sayısını tutmak için kullanılır; amaç gereksiz uyandırma sistem çağrılarını azaltmaktır
- Hâlâ sahiplik ve özyineleme yönetimi yoktur
Sahiplik yönetimi içeren mutex
pthread_t değeri üzerinden kilit sahibini ve durumu açıkça izleyerek hatalı unlock işlemlerini veya özyinelemeli kullanımdaki sorunları yakalar
- Kilit edinme, bırakma ve bekleyen yönetimi tamamen katı atomic işlemlerle kontrol edilir
Özyinelemeli kilit
- İş parçacığı başına iç içe geçme sayacı (depth) eklenerek aynı iş parçacığının kilidi tekrar tekrar almasına izin verilir
- unlock sırasında depth azaltılır; 0 olduğunda gerçek unlock ve uyandırma yapılır
- Her işlem atomic işlemler ve sıkı sahiplik denetimiyle uygulanır
Kalan sorunlar ve gerçek mühendislik pratiği
- Kilidi elinde tutan iş parçacığı anormal biçimde sonlanır ya da ölürse, kilit yönetimi için ayrı bir yönetim listesi, çıkış callback'leri gibi ek mekanizmalar gerekir
- Süreçler arası paylaşılan mutex kullanıldığında da durum değişikliklerinin yönetimi için ek değerlendirmeler gerekir
- POSIX RW lock'larda özyinelemeli iç içe kullanım tanımlı değildir ve uygulamadan uygulamaya değişir; bu yüzden pratikte güvenliği sağlamak zordur
- Yazar, kitabın pratikte gerçekten önemli olan eşzamanlılık meselelerini (futex, özyinelemeli kilitler, asenkron runtime'lar vb.) müfredata dahil etmemesini eleştiriyor
Sonuç
- 'The Art of Multiprocessor Programming', tarihsel veya teorik bakışa fazla yaslandığı için modern paralel programlama pratiğinde önemli olan bilgileri yeterince içermiyor
- Sistemde gerçekten çalışan futex gibi temel senkronizasyon bileşenlerini düzgün biçimde ele almamak, yeni nesil geliştiriciler için somut zararlar doğurabilir
- Yazar, güncel kavramların yansıtılması ve içeriğin pratik açıdan güçlendirilmesi gerektiğini vurguluyor
Kaynaklar
- Tüm kod örnekleri codeberg üzerinde incelenebilir
Henüz yorum yok.