Stellaris’te Optimizasyon ve Yükleme Süreleri

Stellaris geliştirici günlüklerinde bu hafta optimizasyonlar ve yükleme süreleri ile ilgili yapılan değişikliklere dair bilgiler veriliyor.

Herkese merhaba, Paradox’taki Fransız konuşuyor!

Tüm Stellaris ekibi adına konuşmak gerekirse içinde bulduğumuz şartlara rağmen güzel bir yaz tatili geçirdiğimizi umuyoruz.

Hepimiz işe geri dönsek de henüz ofise dönemedik. Önümüzdeki sonbahar ve kış dönemi çok ilginç haberlerle dolu heyecan verici bir dönem olacak. Önümüzdeki haftalarda ve aylarda bu gelişmeleri sizlerle paylaşabileceğimiz için çok heyecanlıyız.

Bugün size programcılarımızın yaz boyunca üzerinde çalıştığı 2.8 yamasıyla ilgili teknik unsurlarla dolu bir günlük ile ilk açılışı yapıyorum. Ekipteki diğer arkadaşlar sonraki günlüklerde eklenecek içerikler ve değişiklikler hakkında size daha fazla bilgi verecektir.

Konuyu daha fazla dağıtmadan haydi biraz thread’lardan konuşalım.

Thread’lar mı? Thread da neyin nesi?

Hayranlarımız arasında güzel bir şaka var: Önce Victoria 3 mü çıkacak yoksa daha fazla Thread kullanan bir PDS oyunu mu?

İnkar etmeyin. Bazılarınız toplantılarımızın böyle olduğunu düşünüyor.
Korkarım bu söylentiyi (yeniden) yoketmem gerekicek. Zira EU4’ten CK3’e tüm PDS oyunları Thread kullanıyor. Hatta Stellaris bile. Bu espriyi ve nereden geldiğini daha iyi açıklamak için biraz tarihte yolculuğa çıkmalıyız. Size tarihi çok sevdiğimi daha önce söylemiştim.

Uzun zaman önce yazılım endüstrisi önümüzdeki 2 yıl içerisinde yapılacak yeni bir işlemcinin bugünkünden 2 kat daha iyi olacağını öngören “Moore Yasası”na dayanıyordu.
Bu durum özellikle işlemcilerin on yıl içerisinde 50 MHz’den 1 GHz’ye çıktığı 90’lı yıllarda geçerliydi. Bu akım 2005 yılında 3.8 GHz hıza ulaşılana kadar devam etti. Ancak sonrasında saat hızı artmamaya başladı. Aradan geçen 15 yıl içerisinde işlemcilerin frekansı az çok aynı seviyelerde seyretti.
Anlaşılan fizik yasaları 3-4 GHz hızın üzerine çıkmayı pratik anlamda pek mümkün kılmıyordu. Bunun yerine donanım geliştiricileri başka yollara yöneldi ve işlemcileri birkaç çekirdeğe ve donanımsal anlamda Thread’lara bölmeye başladı. Bu yüzden günümüzde kullanıcılar işlemci frekansından ziyade işlemcinin kaç çekirdeğe sahip olduğuna dikkat ediyor. Moore Yasası halen geçerli olsa da -oyun terimleriyle ifade etmek gerekirse- işlemci endüstrisi “tall” oynamaya çalışırken “soft cap” limitine dayandı ve taktik değiştirerek yeni “meta” olan “wide” oynamaya başladılar.

Bu değişiklik yazılım endüstrisini değiştirdi. Daha hızlı bir işlemcide kodlar artık daha hızlı çalışabiliyordu. En azından çoğu kod için bu geçerli. Ancak thread’ları ve çekirdekleri kullanmak işin başka bir boyutunu gözler önüne serdi. Programlar işlemcide çalıştıkları işi birden fazla çekirdekte yürütebilmek için bir anda sihirli bir şekilde 2’ye 4’e veya 8’e bölemezler. Bu sorunu halledecek şekilde bir tasarım yapmak da biz programcılara düşüyor.

Threading Sorunları

Burada oyunlara geri dönebiliriz. Forumlarda endişeli bir şekilde “Oyun thread’ları kullanıyor mu?” sorularına rastlıyoruz. Cevap aslında sanılanın aksine evet. Hatta onları o kadar çok kullanıyoruz ki oyunların 2 veya daha az çekirdeğe sahip cihazlarda açılamamasına sebep olan kritik sorunlar ortaya çıkıyor.

Ancak asıl soru şu olmalı: “Thread’ları verimli bir şekilde kullanıyor musunuz?” Bu şekilde sorulduğunda cevabımız “duruma göre” olacaktır. Yukarıda da bahsettiğim gibi daha fazla çekirdeği verimli bir şekilde kullanabilmek daha hızlı bir çekirdek kullanmaktan çok daha karmaşık bir iş. Bizim için burada üstesinden gelmemiz gereken iki ana zorluk mevcut: Sıralama ve Düzenleme

Sequencing yanı sıralama sorunu aynı anda çalışan iki işlemin aynı verilere erişmeye çalışması haline ortaya çıkıyor. Örnek verirsek 2 farklı pop’un üretimlerini hesapladığımızı düşünelim: bir Prikki-Ti ve bir Blorg. Hem mevcut enerji miktarını hem de o miktara eklenecek olan kendi enerji üretimlerini okuyup bunu ekledikten sonra mevcut enerji miktarına yeniden yazıyorlar. Sıralamaya bağlı olarak aynı anda mevcut enerjiyi (100 diyelim) ve kendi üretimlerini (12 ve 3 diyelim, Blorglar için kötü bir gündü) okuyup üretilen enerjiyi mevcut enerjiye ekledikten sonra geri mevcut enerjiye yazıyorlar. Normal şartlarda 115 (100 + 12+ 3) değerini elde etmek istiyoruz. Ancak gerçekte olan durum şu: iki pop da ayrı ayrı 100 sayısını okuyup daha sonra kendi üretimlerini ekleyerek çıkan sonucu 112 ve 103 olarak birbirinin üzerine yazıyor.
Bu sorunu aşmanın basit bir yolu kilit sistemi eklemek. Prikki-Ti kendi üzerine düşen hesapları yapıp sonucu yazana kadar o veriyi kilitliyor. Ardından sıra Blorg’lara geliyor ve onlar da aynı şeyleri yaparken veriyi yeniden kilitliyor. Bu da yukarıdaki sorunu çözerken yeni ve daha büyük bir sorun ortaya çıkarıyor. İşlemler artık sıralı bir şekilde işler ve thread’lar sayesinde elde ettiğimiz bunları eşzamanlı işleme avantajımızı kaybetmiş oluruz. Daha da kötüsü bu kilitleme, kilit açma ve yeniden senkronizasyon işlemleri, her şey tek bir thread üzerinde yapılırsa normalden daha da uzun sürer.

İkinci sorunumuz ise düzenleme veya “düzenlemeye olan bağımlılık”. Bazı durumlarda işlem sırasının değiştirilmesi çıkan sonucu da değiştirebilir. Örneğin Prikki-Ti ve Blorg dostlarımız arasında bir anlaşmazlık çıkmış olsun ve bunu arkadaşça çözmeye karar versinler. Savaş sisteminin her iki tarafı da işleyeceğini biliyoruz ancak potansiyel olarak mevcut yüzlerce savaş işleminden hangisinin önce olacağını bilmiyoruz. Ayrıca potansiyel olarak iki farklı cihazda sıralama da farklı olacaktır. Örneğin sunucuda önce Prikki-Ti hareket ederken karşıdaki cihazda ilk olarak Blorg hareket ediyor olabilir.

#ÖnceBlorgVuruldu
Sunucu tarafında önce Prikki-Ti aksiyona geçerek Blorg’u öldürür. Ardından ölü bir Blorg ateş edemeyeceği için -bu bilimsel bir gerçek- Blorg’un eylemi (muhtemelen başka bir thread’da) reddedilir. Ancak karşıdaki cihazda hesaplama farklı bir şekilde yapılıp (sunucudan daha fazla çekirdeğe sahip olduğu için olabilir) Blorg önce Prikki-Ti’ye saldırıp öldürdü ve bu yüzden Prikki-Ti karşılık veremedi. Ardından her iki oyuncu da kendi verilerinin birbirinden farklı olduğunu görüp senkronizasyon hatası alır.

Elbette bu sorunu da çözmenin bazı yolları mevcut ancak her iki sorunun da çözülebilmesi için tasarımın buna göre yeniden yapılması gerekir. Örneğin ilk durumda her pop’un üretimi ayrı bir yerde toplandıktan sonra bunlar tek bir kerede mevcut miktara eklenebilir. Aynı şekilde iki rakip sorununda da iki tarafın hasarını anında hesaplayıp kaydettikten sonra bu hasarların rakibe yansıtılması şeklinde işlem sırası yeniden düzenlenebilir.

Tahmin edebileceğiniz gibi mevcut bir sistemi düzenlemek yerine yeni bir thread açarak bir şeyler tasarlamak daha kolay oluyor. Eğer bana inanmıyorsanız filolarınızı yeniden düzenlemek için ne kadar çok zaman harcandığına bakın derim. Sonucu bekliyorum.

İyi Haberler

Bunların hepsi çok güzel ancak gelecek yamada tam olarak neler var? Bu gelişmeyi oyun motorumuzun en eski bit’lerine kadar uygulamak için biraz zaman harcadığımı duyunca sevineceksiniz: dosyalar ve modellerin yükleme sistemi.

Uzun bir süre boyunca bu iş için 3. parti yazılımlar kullanmıştık. Bu bizi bir sürü zahmetten kurtardı fakat yeni thread’lar konusunda da oldukça kötü olduğunu farkettik. Bazı zamanlarda daha fazla çekirdeğin oyunu daha da yavaşlatması durumu ve bahsettiğim kilitleme olayıyla ilgili sorunlar vardı.
Bu gelişmeler diğer birkaç optimizasyonla birlikte oyunun açılış hızını dramatik bir şekilde azalttı diyebilirim.
Bunun nasıl olduğunu anlatmak için bin kelime daha yazabilirim ancak bu videonun benden daha iyi anlatacağını düşünüyorum.

Bu karşılatırma benim evimdeki i7 2600K ve bir SSD sürücü kullanan naçizane bilgisayarım tarafından yapıldı. Her ikisi de henüz sıcak açılışlardı -yani oyun yeni açılmıştı- ancak denemelerimde soğuk açılışlarda da ciddi farklılıklar yarattığını gördüm.

En iyi hızlanmayı elde etmek için yeni çıkan DirectX11 Beta sürümünü kullanmanız gerekiyor. Evet, doğru duydunuz: yeni yama eski DX9 yerine -ilk olarak Tantalus’taki arkadaşlarımız tarafından Stellaris’in konsol sürümü için de kullanılan- DX11 kullanan bir açık beta içeriyor. Görsel olarak aynı olsa da grafikleri işlemek için DX11 kullanmak DX9 ile elde edilmesi zor hatta imkansız olan bir çoklu threading optimizasyonu sağlıyor. Eski DX9 ile oynamak başlangıçta size biraz hız kazandırıyor gibi olsa da -açılış ekranı daha hızlı olabilir- oyun modelleri ve kaplamalar yüklenirken DX11’de olduğu gibi yükleme çubuğunda bir sıçrama görme olasılığınız çok düşük.

Bu optimizasyonların bir kısmı Clausewitz’in yeni sürümlerine de uygulandı ve CK3 çıktığında bunu deneyimleyebileceksiniz. Imperator’un da bundan yararlanması gerekiyor. Hatta belki EU4 ve HOI4’e de uygulamak mümkün olabilir ancak EU4’te yaptığım denemeler sonuçların Stellaris ve CK3’te hızlanmaların aksine pek iç açıcı olmadığını gösteriyor.

Stellaris’i hızlandırmak için yapılan optimizasyonlar hakkında daha fazla teknik detay öğrenmek istiyorsanız blogumda yeni yayınladığım makaleye göz atabilirsiniz.

Şimdilik sizi bunlarla başbaşa bırakacağım. Önümüzdeki ay HOI4 programcılarına liderlik etmek için transfer olacağımdan bu muhtemelen Stellaris’teki son geliştirici günlüğüm oluyor. Bu optimizasyonları veda hediyem olarak görebilirsiniz.
Stellaris’te fazla vaktim kalmamış olabilir ancak endişelenmeyin. Ben gitsem bile Jeff sizinle olacak.

Yazar: Umut Öksüz

Yorumla

STRATEGYTURK

Strategyturk'te strateji oyunlarından haberleri, yama notlarını, geliştirici günlüklerini ve daha birçok içeriği Türk strateji oyuncularına Türkçe bir biçimde sunuyoruz. Aynı zamanda yeni çıkan strateji oyunlarının ve eklentilerinin incelemelerini yapıyor, bu oyunlara dair sürekli olarak içerik oluşturuyoruz.

Sosyal medya sayfalarımızı takip ederek strateji oyunlarındaki gelişmelerden haberdar olabilirsiniz.

STRATEGYTURK TWITTER

Stellaris'te Necroidler ve Mishar Cabal #stellaris https://t.co/uVqr3b81RF
Hearts of Iron IV'te Türkiye Odak Ağacı #hoi4 https://t.co/UcONXW5zND

Strategyturk Arşiv