fastDOOM neden hızlı?
(fabiensanglard.net)- 1993’ün yüksek performanslı PC sınıfındaki IBM PS/1 486-DX2 66MHz’te orijinal DOOM,
demo1bazında 21,5fps verirken fastDOOM aynı koşullarda 30,1fps’ye çıkarak DOS portu optimizasyonundaki farkı gösteriyor - fastDOOM; Linux DOOM çekirdeği, Heretic I/O, APODMX ve
DOOM.EXEtersine ayrıştırmasına dayalı Mode Y grafik I/O birleşiminden oluşan PCDOOM v2’den doğdu - 52 sürüm ve 3.042 commit derlenip benchmark edildiğinde performans artışının tek başına modern bir derleyiciden değil, küçük optimizasyonların birikiminden geldiği görüldü
- Büyük iyileştirmeler arasında durum çubuğu render’ını atlama,
FixedDivinline etme, BSP dolaşımı optimizasyonu, visplane render’ını atlama, pointer dolaylı başvurularını kaldırma ve renderer’a göre ayrı çalıştırılabilir dosyalar yer alıyor - Grafik modlarında avantaj/dezavantaj CPU ve bus’a göre değişiyor; yavaş CPU’larda Mode Y avantajlıyken hızlı CPU ve VLB/PCI ortamlarında Mode 13h veya VESA direct daha iyi olabilir, ancak VESA 2.0 gibi kısıtlar sürüyor
486-DX2’de ortaya çıkan performans farkı
- IBM PS/1 486-DX2 66MHz “Mini-Tower” model 2168’de orijinal DOOM
doom.exe -timedemo demo1ile çalıştırıldığında1710 gametics in 2783 realticssonucu çıkıyor- DOOM fps’i doğrudan yazdırmadığı için
1710/2783*35ile hesaplamak gerekiyor; sonuç 21,5fps
- DOOM fps’i doğrudan yazdırmadığı için
- Aynı makinede
fdoom.exe -timedemo demo1çalıştırıldığında1710 gametics in 1988 realtics, yani 30,1fps görülüyor doom2’nindemo1’i gibi daha ağır haritalarda orijinal 16,8fps’den fastDOOM’da 24,9fps’ye çıkarak %48 hızlanıyor- Ancak joystick ve network gameplay desteği kaldırılmış; dolayısıyla tüm işlevleri aynen koruyan bir port değil
fastDOOM’un çıktığı kod soy ağacı
- DOOM başlangıçta NeXT Workstation üzerinde geliştirildi ve çekirdek kodun büyük kısmı ile küçük I/O alt sistemlerine ayrıldığı için port edilmesi kolay bir yapıya sahipti
- Ticari DOS sürümü id Software’ın yazdığı DOS I/O’yu kullanıyordu, ancak proprietary ses kütüphanesi DMX bağımlılığı nedeniyle 1997’de olduğu gibi açık kaynak yapılamadı
- Yayımlanan kod, Bernd Kreimeier’in motoru anlatan bir kitap projesi yürütürken düzenlediği Linux sürümüydü
- DOS sürümü PCDOOM v2 şu bileşimle yeniden kuruldu
- Linux DOOM’un çekirdeği
- Heretic’in I/O’su
- DMX’i taklit etmek için APODMX
DOOM.EXEtersine ayrıştırmasından reverse engineering ile çıkarılani_ibm.cgrafik I/O’su
- fastDOOM bu PCDOOM v2’yi çıkış noktası olarak aldı
Sürümler ve commit’lerle izlenen performans değişimi
- Victor “Viti95” Nieto fastDOOM’u sık sık yayımladı, her sürüme tag koydu ve bir commit’in tek bir işi yapacağı şekilde yönetti
- fastDOOM’un Git geçmişi 3.042 committen oluştuğu için commit bazında performans değişimleri izlenebildi
- 52 fastDOOM sürümü, PCDOOM v2 ve orijinal
DOOM.EXEindirilerek-timedemo demo1çalıştıranRUN.BATbir Go programıyla oluşturuldu; testler mTCPNETDRIVEile mount edilerek yapıldı- Koşullar
DOOM.WAD, sound on, screen size 10 idi - Tüm suite 5 kez çalıştırılıp ortalama fps grafiğe döküldü
- Koşullar
- PCDOOM v2 OpenWatcom 2 ile derlenmiş olmasına rağmen orijinal
DOOM.EXE’e kıyasla büyük bir iyileşme göstermedi; bu yüzden fastDOOM’daki artışı yalnızca modern derleyici kullanımıyla açıklamak zor - Dosya boyutu grafiğinde ilk çalışmaların kod temizliği ve silme yoluyla daha hafif hâle getirme yönünde olduğu görüldü
Performansı artıran sürüm bazlı değişiklikler
- 3.042 build’in tamamı timedemo’dan geçirilirse yaklaşık 9 gün sürebileceği için commit bazında benchmark, hız artışının büyük olduğu
v0.1,v0.6,v0.8,v0.9.2,v0.9.7odağında yapıldı -
fastDOOM v0.1
v0.1220 committen oluşuyor- En büyük patch, build 36’daki e16bab8
- “Crispy optimization”, durum çubuğu yüzdesi değişmediğinde render’ı no-op hâline getirerek scrap buffer render’ını ve ekrana blit’i önlüyor
- Yalnızca bu değişiklikle 2fps artış görüldü
- build 167’deki a9359d5,
FixedDiv’i makro olarak inline ediyor - build 207’deki 9bd3f20, PSX Doom optimizasyonunu alarak BSP dolaşım yöntemini iyileştiriyor
- build 212’deki dc0f48e, yatay yüzey render fonksiyonu
R_MakeSpans’i inline ediyor - Tüm commit’ler içinde silme commit’i sayısı 100; yani yaklaşık yarısı kod silme idi
-
fastDOOM v0.6
-
fastDOOM v0.8
v0.8282 committen oluşuyor- sound system kararsız olduğu için timedemo ses olmadan yapılıp fps düzeltildi
- Bu sürüm text-mode renderer’a odaklıydı; build 670 ve build 730’da Crispy optimization çıkınca regresyon oluştu
- Başlıca iyileştirmeler şunlar
-
fastDOOM v0.9.2 ve v0.9.7
v0.9.2110 commit’ten oluşuyor; skyflatnum karşılaştırma optimizasyonu, Mode Y içinR_DrawColumnoptimizasyonu veR_DrawSpankod temizliği başlıca değişikliklerv0.9.7293 commit olarak tanıtılmış olsa da komut çıktısı 294 gösteriyor- Bu sürümde birden çok benchmark çalıştırılsa da noise azaltılamadı
- Başlıca değişiklikler x86 ASM değişiklik testleri, 386SX için CPU seçimi ve CR2 optimizasyonu,
R_DrawSpan386SXiçin ESP optimizasyonu, ASM fuzz column render’ı tabanlı kod ve döngü başına CMP karşılaştırmasını kaldırma gibi işlerdi
Mode 13h, Mode Y ve VESA direct için seçim ölçütleri
- fastDOOM, 386, 486, Pentium, Cyrix ile ISA, VLB, PCI gibi farklı CPU ve video bus kombinasyonları için çeşitli optimizasyonları araştırıyor
- IBM PS/1 486-DX2 66MHz’te Mode Y yerine Mode 13h kullanan optimizasyon daha yavaştı
-
Mode 13h
- VGA’nın dört VRAM bank’ına veri dağıtma işini donanım yapar; CPU’ya tek bir lineer 320x200 framebuffer gibi görünür
- VRAM’de double buffering yapılamadığı için RAM’de buffer’layıp sonra yeniden VRAM’e kopyalamak gerekir; bu yüzden byte’lar iki kez yazılır
- Motorun VSYNC’te block olması gerekir
-
Mode Y
- VGA bank’larına ayrı ayrı erişilebildiği için VRAM triple buffering mümkündür ve byte’lar VRAM’e doğrudan yalnızca bir kez yazılabilir
- Bank seçimi için yavaş
OUTkomutu gerekir - Latch aracılığıyla iki VGA bank’ına aynı anda yazılırsa yatay piksel çoğaltma yapılabilir ve low-detail mode elde edilebilir
- invisible Specter render’ı VRAM readback gerektirdiği için çok daha yavaştır
- John Carmack’ın açıklamasına göre DOOM, 320×200×256 VGA modunda Mode X’e benzer interleaved planar mode kullandı ve üç display page’i döndürdü
- Texture mapping doğrudan video memory’ye yapıldığında birçok video kartında %10~%15 ek hız alınabiliyordu
- Main memory buffering’e kıyasla tearing olmadan page flip de mümkündü
- Heretic 1994’te çıktı ve o dönem donanım değişimiyle Mode 13h daha cazip bir seçenek hâline geldiği için Raven, DOOM motorunu bu yönde değiştirdi
- fastDOOM kullanıcıya birden çok çalıştırılabilir dosya sunar
FDOOM.EXEFDOOM13H.EXEFDOOMVBD.EXE
-
fastDOOM’un Mode 13h ve VESA direct’i
- fastDOOM’un Mode 13h’si RAM’deki tek bir framebuffer’a render edip tüm sahne bittiğinde VRAM’e kopyalar
- VSYNC’i zorunlu kılmadığı için flickering oluşabilir
- Yavaş 8-bit ISA bus’ta yalnızca değişen pikselleri aktaran differential copy kullanılır
- 16-bit ISA, VLB, PCI gibi daha hızlı bus’larda tüm backbuffer
REP MOVSile kopyalanır - Viti95’in testlerine göre 486 CPU için en iyi mod, 320×200’e yönelik VESA direct mode olan
FDOOMVBD.EXE- Mode Y’nin avantajlarıyla Heretic’in optimize edilmiş render kodunu birleştirir
- Buffer geçişinde frame başına bir
OUTdışındaOUTkomutundan kaçınır - LFB etkin bir VLB veya PCI grafik kartı ve VESA 2.0 desteği gerektirir; low-detail ve potato-detail mode’larda yavaştır
- IBM 2168, VESA 2.0 desteklemediği için
FDOOMVBP.EXEveFDOOMVBDçalıştırıldığında hata oluşur
İşe yaramayan denemeler ve genel izlenim
- OpenWatcom’un işlemciye özel flag’leri olan
4r/4sve3r/3sde denendi ancak bırakıldı- wcc386’nin 386 flag’leri ve 486 flag’leri denendi; sonuçta 386 sürümü her zaman daha hızlı görünüyordu
- Viti95’in fastDOOM derleyicisini OpenWatcom v2’den DJGPP’ye, yani GCC’ye taşıma hedefi de var
- Çünkü aynı kaynakta GCC’nin daha hızlı kod ürettiği görüldü
- Ya da OpenWatcom v2’nin performans farkını azaltacak şekilde geliştirilmesi de iyi bir seçenek olarak duruyor
- fastDOOM’un performansı, Crispy, PSX, GBA ve Lee Killough’un mevcut iyileştirmelerinden yararlanıp çok sayıda yeni optimizasyon eklemenin sonucu
- Ken Silverman’ın fikirleri ve kodunun bir kısmı da UMC Green CPU’ya yönelik render fonksiyonlarına girdi ve o donanımda büyük hız artışı sağladı
- fastDOOM tek bir sihirli değişiklik değil; binlerce küçük optimizasyonun birikerek orijinal DOOM’dan daha hızlı bir DOS portuna dönüşmesinin örneği
1 yorum
Hacker News yorumları
Darboğazların çoğu zaman beklediğiniz yerde olmadığını gösteren, profil çıkarma ve ölçüm gerektiğine dair iyi bir örnek
Durum çubuğundaki yüzde göstergesinin render edilmesiymiş; Doom’un yapısını iyi bilen bir uzman için nispeten bariz olabilirdi ama önceden bunun darboğaz olduğunu asla tahmin edemezdim
https://www.granola.ai/blog/dont-animate-height
En kötü durumda, durum çubuğunda skoru göstermek tüm karenin neredeyse 1/6’sını harcıyor ve yavaşlamanın başladığı eşiği düşürüyordu; yama ise skorun saklanma ve gösterilme yöntemini neredeyse sabit zamana yaklaştırarak mevcut en iyi durumdan bile biraz daha hızlı hale getirdi
https://www.smwcentral.net/?p=section&a=details&id=35746
Saydamlık, katmanlama, yeniden çizim ve özellikle bellek ayırmayı tetikleme nedeniyle UI render etme ölümcül olabilir; yeniden çizmeden önce eski değerle yeni değeri karşılaştırmak büyük fayda sağlar
CSS’te de katmanların ve saydamlığın darboğaz olduğu bir proje vardı; o zaman asıl kritik nokta katman sayısını azaltmaktı
6 dakikalık yüklemeyi 2 dakikanın altına indirdi
https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
https://news.ycombinator.com/item?id=10974929
Asıl hedef kitlesi ben olmayabilirim ama mTCP’nin NETDRIVE’ı ilgimi çekti
O kadar eski zamanlarda bile kullanılabilir ağ depolama seçenekleri olabileceğini bilmiyordum; bakınca https://www.brutman.com/mTCP/mTCP_NetDrive.html sayfasını buldum ve gerçekten harika
NetDrive’ın, başka bir makinenin barındırdığı uzak disk imajına DOS’ta bir sürücü harfiyle bağlanmış yerel aygıt gibi erişmeyi sağlayan bir aygıt sürücüsü olduğu söyleniyor
Aşırı yavaştı; öğrenciler ders başında kelime işlemciyi açmak için 5-10 dakika harcıyordu, Xerox Alto da sürücü için ağ mount’u kullanıyordu
Ağ varsa birileri kısa süre sonra dosya kopyalamak ister; bunu yapmanın en rahat yolu da onu yerel dosya sistemi gibi göstermektir
DOS’ta yerleşik ağ desteği olmadığı için bu konuda geride kalmıştı ve doğrudan yapılması gereken çok iş vardı
DOS tarafında sürücü veya yapılandırma olmadan ağ blok aygıtına okuma-yazma erişimi mümkün oluyor; paylaşımlı disk gibi kullanırsanız çabuk bozulur ve daha çok blok aygıtına yakındır
Sihir gibi geliyor ama iPXE, BIOS’u yamayıp disk erişimlerini iSCSI’ye gönderiyor gibi
FTP ve telnet gibi şeyler elbette vardı ama uzak mount gerçekten kullanılıyor muydu, yoksa düşük bant genişliği yüzünden imkânsız mıydı merak ediyorum
Ken Silverman’ın katıldığı GitHub başlığı hazine gibi
FastDOOM’un yazarıyla Ken’in anlaşılması güç 486 register’ları ve clock cycle verimliliği konularına dalışını izlemek şaşırtıcı
Doom’un hâlâ performans iyileştirmeleri almasını önemseyen birilerinin olması sevindirici
O scripting kelimenin tam anlamıyla ilk “kodlamam”dı ve bir anlamda tüm kariyerimi ve servetimi KenS’e borçluyum; bu çok hoş
Özellikle bellek erişiminin çok yavaş olduğu 386SX ve önbelleksiz 386DX’te CR2 ve CR3’ü scratchpad register gibi kullanma fikri hoşuma gitti
Kesintileri kapatmadan ESP’yi döngü sayacı olarak kullanma tekniği de dahiyane; bunu her zaman geçerli bir stack konumunu gösterecek şekilde garanti ediyor
FastDOOM’da burada pek ele alınmayan özellik, envaiçeşit tuhaf video modu
IBM MDA metin modu: https://www.youtube.com/watch?v=Op2tr2lGK6Y
EGA & Plantronics ColorPlus: https://www.youtube.com/watch?v=gxx6lJvrITk
Klasik mavi-pembe CGA: https://youtu.be/rD0UteHi2qM
‘ANSI from Hell’ hilesini kullanan CGA 320x200x16: https://www.youtube.com/watch?v=ut0V1nGcTf8
Hercules: https://www.youtube.com/watch?v=EEumutuyBBo
Çoğu, renk yeniden eşleme gibi işler yüzünden VGA’dan daha yavaş çalışıyor gibi görünüyor
CGA ile çalıştırmak zorunda kalsaydım hoşuma gitmezdi; hâlâ yaşıyor olsaydım Tandy 1000 TL/2 için muhtemelen bir 286 derlemesine ihtiyaç duyardım
Backend uygulamalarındaki “modern” Clean Architectureı akla getiriyor
“IBM PS/1 486-DX2 66Mhz, ‘Mini-Tower’, model 2168. Ergenken hep sahip olmak istediğim ama alamadığım bilgisayar” kısmı dikkat çekici
1992 civarında kendi topladığım dördüncü PC’yi kullanıyordum ve Marlborough MA’daki KCS bilgisayar fuarları kurcalamayı sevenler için muazzam bir kaynaktı diye düşünüyorum
Parça alıp PC toplar, bir süre kullanıp satar, sonra yeniden parça alırdım
1992’nin sonlarında ULSI 487 matematik yardımcı işlemcili bir 486-DX3 100 çalıştırıyordum; bir süre kampüsteki en hızlı PC, hatta belki de en hızlı bilgisayardı denebilir
Birçok Pentium modelinden daha hızlıydı ve matematik hatası da üretmiyordu
Son derlemeyi, onur tezim için bir gaz/dizel kojenerasyon tesisini 21 sayfalık bir Excel elektronik tablosuyla simüle ederken yeniden hesaplama süreleri çok uzadığı için gerekçelendirmiştim
Bölümüm çevre bilimiydi ama kariyerim tamamen bilgisayar oldu
1992’de böyle bir bilgisayar alamamış birine bunu özellikle zorlaştırmaya gerek var mıydı
Üstelik “DX3” diye bir şey yok; ilk 100MHz 486 olan DX4 Mart 1994’te çıktı, bu yüzden 1992 sonlarında çalıştırdığı iddiası doğru görünmüyor
Bizim evdeki ilk bilgisayar, 1992 civarında aldığımız ve o zaman bile çok eskimiş olan XT’yi saymazsak, 1995 başında aldığımız 66MHz 486-DX2 idi
Aradan onlarca yıl geçmişken bile, 3 yıllık handikaba rağmen benim bilgisayarımdan hızlı olduğu söylenen imkânsız bir bilgisayarla tuhaf biçimde övünülmesi nedense gururumu incitiyor
1992 civarında yoksul bir üniversite öğrencisiydim ve kredi birliğinden yaklaşık 2.000 dolar kredi çekip bir 486 DX2-50 aldım
Bugünün parasıyla oldukça temel bir bilgisayara 4.000 doların üzerinde para harcamış oldum ve o makinede DOS ile Linux’u çift önyüklemeli kullanıyordum
Bakınca, standart 487’nin aslında 486SX’i devre dışı bırakıp onun yerine geçen tam bir 486DX olduğunu öğrendim
Acaba benim bilmediğim başka müthiş bir yardımcı işlemci miydi
Gerçekten ezip geçmiş
Sık sürüm çıkarmasının yanı sıra Viti95, tek bir commit’in tek bir işi yaptığı ve her sürümün etiketlendiği mükemmel bir Git disiplini göstermiş
https://fabiensanglard.net/fastdoom/#:~:text=one%20commit%20...
“fastDOOM’u öğrenene kadar Ibuprofen alarak oynamaya razı olmuştum” cümlesindeki Ibuprofen ile ne kastedildiğini anlamadım
Yazar görürse, belgenin genelinde John Carmack’in soyadı “Carnmack” diye hatalı yazılmış
Modern yazılımların neden yavaş olduğunu ve bu tür optimizasyonların neden yapılmadığını alaycı olmayan bir şekilde açıklarsak, bunu standardizasyon/optimizasyon hipotezi ile anlatabiliriz
Bir şey standart hâline gelince optimizasyon peşinden gelir
Çünkü standardın tüm testlerini geçerken en hızlısı olmak istersiniz
Doom da artık ister yeni CPU ister tost makinesi olsun her yere port edilen standart bir oyun oldu; e-posta protokolleri veya tarayıcı standartları olan WebRTC, QUIC vb. de benzer
Modern web uygulamalarının ya da Electron uygulamalarının hızlı olmamasının nedeni keşif aşamasında olmaları
Her gün yeni kullanıcı ihtiyaçlarına göre güncelleniyorlar ve performans açısından, engel olmayacak kadar hızlı olmaları yeterli
Bu yüzden IRC uygulamaları çok hızlıyken Slack ve Teams her zaman yavaş olmak zorunda kalabiliyor
Sürümler arasında geri gidip iyileştirmeleri ve gerilemeleri kontrol etmek önemsiz bir iş değil
Bazı optimizasyonlar sonradan bulunan hatalar yaratabilir; gerçekten gerekli bir özellik de performansı düşürebilir
Bu yüzden her sürümden önce otomatik çalışan performans testleri koymak hayatı kolaylaştırır; performans sorunu bulunursa her zamanki gibi bir regresyon testi yazarsınız
Sonuçta söylemek istediğim şey performans testi yapın