1 puan yazan GN⁺ 2025-03-05 | 1 yorum | WhatsApp'ta paylaş
  • 1993’ün yüksek performanslı PC sınıfındaki IBM PS/1 486-DX2 66MHz’te orijinal DOOM, demo1 bazı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.EXE tersine 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, FixedDiv inline 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 demo1 ile çalıştırıldığında 1710 gametics in 2783 realtics sonucu çıkıyor
    • DOOM fps’i doğrudan yazdırmadığı için 1710/2783*35 ile hesaplamak gerekiyor; sonuç 21,5fps
  • Aynı makinede fdoom.exe -timedemo demo1 çalıştırıldığında 1710 gametics in 1988 realtics, yani 30,1fps görülüyor
  • doom2’nin demo1’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.EXE tersine ayrıştırmasından reverse engineering ile çıkarılan i_ibm.c grafik 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.EXE indirilerek -timedemo demo1 çalıştıran RUN.BAT bir Go programıyla oluşturuldu; testler mTCP NETDRIVE ile 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ü
  • 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ü
    • bf0e983: sound recording kaldırıldı
    • 5f38323: error code dizgeleri silindi
    • 8b9cac5: TASM, NASM ile değiştirildi

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.7 odağında yapıldı
  • fastDOOM v0.1

    • v0.1 220 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

    • v0.6 33 commit’ten oluşuyor
    • build 342’deki 22819fd, gereksiz visplane render’ını atlıyor
    • build 359’daki 40e0d4b ve build 360’taki ccd296f, player pointer dolaylı başvurularını azaltıyor
    • build 369’daki f29e665, screenspace line splitter’ı inline ediyor
  • fastDOOM v0.8

    • v0.8 282 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
      • f279b7d: FDOOM.EXE, FDOOM13H.EXE gibi renderer’a göre çalıştırılabilir dosyaların ayrılması
      • 1874ee8: derleyici debugging’in devre dışı bırakılması
      • 6aae724: Crispy optimization’ın geri getirilmesi
      • 1366ebf: mümkün olduğunda daha az kodun derlenmesi
  • fastDOOM v0.9.2 ve v0.9.7

    • v0.9.2 110 commit’ten oluşuyor; skyflatnum karşılaştırma optimizasyonu, Mode Y için R_DrawColumn optimizasyonu ve R_DrawSpan kod temizliği başlıca değişiklikler
    • v0.9.7 293 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_DrawSpan386SX iç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ş OUT komutu 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.EXE
    • FDOOM13H.EXE
    • FDOOMVBD.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 MOVS ile 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 OUT dışında OUT komutundan 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.EXE ve FDOOMVBD çalıştırıldığında hata oluşur

İşe yaramayan denemeler ve genel izlenim

  • OpenWatcom’un işlemciye özel flag’leri olan 4r/4s ve 3r/3s de 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

 
GN⁺ 2025-03-05
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

    • Örneğin bir uygulamanın anlaşılmaz biçimde CPU’nun %60’ını ve GPU’nun %25’ini kullandığı, sonunda bunun küçük bir CSS animasyonundan kaynaklandığının anlaşıldığı bir vaka var
      https://www.granola.ai/blog/dont-animate-height
    • SNES için Super Mario World’de oyuncu skorunun gösterimi çok verimsiz olduğu için kare süresinin yaklaşık 1/6’sını yiyen bir optimizasyon vakası da aklıma geliyor
      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
    • Oyun geliştiriciler açısından bu tür yavaşlamalar yaygındır
      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ı
    • En sevdiğim örnek GTA Online yükleme süresi sorunu; sonuçta 10 MB’lık bir JSON dosyasının yanlış işlenmesinden kaynaklanıyordu ve bunu kurum dışından biri izini sürerek buldu
      6 dakikalık yüklemeyi 2 dakikanın altına indirdi
      https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
    • npm’in gösterişli terminal ilerleme çubuğu yüzünden normalden 2 kat yavaş olduğu olayı aklıma geliyor
      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

    • 90’ların başında okuldaki bilgisayar laboratuvarında yaklaşık 25 Mac Plus, AppleTalk üzerinden bir Mac II’ye papatya zinciriyle bağlıydı ve tüm Plus’lar dosya sistemini Mac II’den mount ediyordu
      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ı
    • iPXE ile bir iSCSI hedefinden DOS’u ağ üzerinden boot etmeye yarayan temiz bir numara var
      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
    • DOS döneminde de NAS veya WebDAV mount var mıydı merak ediyorum
      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

    • KenS’i gerçekten çok uzun zaman sonra hatırladım; 90’larda Duke3D modlama sahnesinde çok aktifti
      O scripting kelimenin tam anlamıyla ilk “kodlamam”dı ve bir anlamda tüm kariyerimi ve servetimi KenS’e borçluyum; bu çok hoş
    • Geçen yıl benzer bir 2.5D render motoru yaparken Build Engine’in pek bilinmeyen bir kısmı hakkında Ken Silverman’a e-posta gönderdim; sanki daha dün onun üzerinde çalışmış gibi yanıt verdi
    • İçinde gerçekten mücevher gibi bilgiler var
      Ö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

    • Tandy Graphics Adapter desteği de gelse güzel olurdu
      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
    • Gerçekten harika; oyunun bu tür yönlerinin neden ayrıştırılması gerektiğini çok iyi gösteriyor
      Backend uygulamalarındaki “modern” Clean Architectureı akla getiriyor
    • IBM MDA metin modu berbat... bu yüzden güzel
  • “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

    • “Vay be” denecek bir şey mi, emin değilim
      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
    • Kesinlikle anıları canlandırıyor
      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
    • 486DX’e 487 mi; 487’nin yalnızca SX çiplerinde işe yaradığını sanı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
    • “Birçok Pentium modelinden daha hızlıydı ve matematik hatası da üretmiyordu” ise bu tam anlamıyla övünülecek bir şey
      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

    • Düşük kare hızı yüzünden oluşan baş ağrısı demek olabilir
  • 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