1 poin oleh GN⁺ 2025-03-05 | 1 komentar | Bagikan ke WhatsApp
  • Pada IBM PS/1 486-DX2 66MHz, PC kelas tinggi tahun 1993, DOOM asli mencatat 21,5fps berdasarkan demo1, sementara fastDOOM naik hingga 30,1fps dalam kondisi yang sama, menunjukkan perbedaan optimasi port DOS
  • fastDOOM berawal dari PCDOOM v2, yang menggabungkan core Linux DOOM, I/O Heretic, APODMX, dan I/O grafis Mode Y berbasis reverse assembly DOOM.EXE
  • Dari hasil membangun dan membenchmark 52 rilis serta 3.042 commit, peningkatan performa bukan berasal dari satu compiler modern, melainkan dari akumulasi optimasi kecil
  • Peningkatan besar mencakup melewati rendering status bar, inline FixedDiv, optimasi traversal BSP, melewati rendering visplane, menghapus indirect reference pointer, dan memisahkan executable per renderer
  • Mode grafis punya kelebihan dan kekurangan tergantung CPU dan bus; pada CPU lambat Mode Y lebih menguntungkan, dan pada CPU cepat serta lingkungan VLB/PCI Mode 13h atau VESA direct bisa lebih baik, tetapi tetap ada batasan seperti VESA 2.0

Perbedaan Performa yang Terlihat pada 486-DX2

  • Saat DOOM asli dijalankan dengan doom.exe -timedemo demo1 di IBM PS/1 486-DX2 66MHz model “Mini-Tower” 2168, hasilnya 1710 gametics in 2783 realtics
    • DOOM tidak menampilkan fps secara langsung, sehingga harus dihitung dengan 1710/2783*35; hasilnya 21,5fps
  • Di mesin yang sama, menjalankan fdoom.exe -timedemo demo1 menghasilkan 1710 gametics in 1988 realtics, yaitu 30,1fps
  • Pada map yang lebih berat seperti demo1 di doom2, performa naik dari 16,8fps pada versi asli menjadi 24,9fps pada fastDOOM, lebih cepat 48%
  • Namun dukungan joystick dan network gameplay dihapus, jadi ini bukan port yang mempertahankan semua fitur apa adanya

Silsilah Kode yang Melahirkan fastDOOM

  • DOOM awalnya dikembangkan di NeXT Workstation, dan memiliki struktur yang mudah di-porting karena sebagian besar terdiri dari kode core dan subsistem I/O kecil
  • Versi DOS komersial menggunakan I/O DOS yang ditulis id Software, tetapi karena dependensi pada DMX, proprietary sound library, versi itu tidak bisa langsung dijadikan open source pada 1997
  • Kode yang dirilis adalah versi Linux yang dirapikan oleh Bernd Kreimeier saat mengerjakan proyek buku untuk menjelaskan engine tersebut
  • Versi DOS PCDOOM v2 direkonstruksi dengan kombinasi berikut
    • Core Linux DOOM
    • I/O Heretic
    • APODMX untuk meniru DMX
    • I/O grafis i_ibm.c yang direkayasa balik dari reverse assembly DOOM.EXE
  • fastDOOM menggunakan PCDOOM v2 ini sebagai titik awal

Melacak Perubahan Performa lewat Rilis dan Commit

  • Victor “Viti95” Nieto sering merilis fastDOOM dan memberi tag pada setiap rilis, serta mengelola agar satu commit mengerjakan satu hal
  • Riwayat Git fastDOOM terdiri dari 3.042 commit, sehingga perubahan performa per commit bisa dilacak
  • 52 rilis fastDOOM, PCDOOM v2, dan DOOM.EXE asli diunduh, lalu program Go digunakan untuk membuat RUN.BAT yang menjalankan -timedemo demo1; semuanya di-mount dengan mTCP NETDRIVE untuk pengujian
    • Kondisinya adalah DOOM.WAD, sound on, screen size 10
    • Seluruh suite dijalankan 5 kali dan fps rata-ratanya digambarkan dalam grafik
  • PCDOOM v2 dibangun dengan OpenWatcom 2, tetapi peningkatannya dibanding DOOM.EXE asli tidak besar, sehingga peningkatan fastDOOM sulit dijelaskan hanya dari penggunaan compiler modern
  • Pada grafik ukuran file, pekerjaan awal mengarah pada membuat program lebih ringan lewat perapian dan penghapusan kode
    • bf0e983: menghapus sound recording
    • 5f38323: menghapus string error code
    • 8b9cac5: mengganti TASM dengan NASM

Perubahan per Rilis yang Mendorong Performa

  • Jika seluruh 3.042 build dijalankan dengan timedemo, prosesnya bisa memakan waktu sekitar 9 hari, sehingga benchmark per commit difokuskan pada v0.1, v0.6, v0.8, v0.9.2, dan v0.9.7, yang peningkatan kecepatannya besar
  • fastDOOM v0.1

    • v0.1 terdiri dari 220 commit
    • Patch terbesar adalah e16bab8 pada build 36
      • “Crispy optimization” membuat rendering menjadi no-op saat persentase status bar tidak berubah, sehingga menghindari rendering scrap buffer dan blit ke layar
      • Satu perubahan ini terbukti menaikkan performa 2fps
    • a9359d5 pada build 167 meng-inline FixedDiv sebagai macro
    • 9bd3f20 pada build 207 mengambil optimasi PSX Doom untuk memperbaiki cara traversal BSP
    • dc0f48e pada build 212 meng-inline fungsi rendering permukaan horizontal R_MakeSpans
    • Dari seluruh commit, 100 commit adalah penghapusan, sehingga sekitar setengahnya merupakan penghapusan kode
  • fastDOOM v0.6

    • v0.6 terdiri dari 33 commit
    • 22819fd pada build 342 melewati rendering visplane yang tidak perlu
    • 40e0d4b pada build 359 dan ccd296f pada build 360 mengurangi indirect reference pada player pointer
    • f29e665 pada build 369 meng-inline screenspace line splitter
  • fastDOOM v0.8

    • v0.8 terdiri dari 282 commit
    • Karena sound system tidak stabil, timedemo dilakukan tanpa sound lalu fps dikoreksi
    • Rilis ini berfokus pada text-mode renderer, dan terjadi regresi pada build 670 serta build 730 ketika Crispy optimization hilang
    • Peningkatan utamanya sebagai berikut
      • f279b7d: memisahkan executable per renderer seperti FDOOM.EXE, FDOOM13H.EXE, dan lainnya
      • 1874ee8: menonaktifkan debugging compiler
      • 6aae724: memulihkan Crispy optimization
      • 1366ebf: hanya mengompilasi kode yang lebih sedikit jika memungkinkan
  • fastDOOM v0.9.2 dan v0.9.7

    • v0.9.2 terdiri dari 110 commit, dengan perubahan utama berupa optimasi perbandingan skyflatnum, optimasi R_DrawColumn untuk Mode Y, dan perapian kode R_DrawSpan
    • v0.9.7 diperkenalkan sebagai 293 commit, tetapi output command menunjukkan 294 commit
    • Pada rilis ini, noise tidak bisa dikurangi meski benchmark dilakukan berkali-kali
    • Perubahan utama mencakup pengujian perubahan x86 ASM, pemilihan CPU untuk 386SX dan optimasi CR2, optimasi ESP untuk R_DrawSpan386SX, kode berbasis rendering ASM fuzz column, serta penghapusan perbandingan CMP per loop

Kriteria Memilih Mode 13h, Mode Y, dan VESA direct

  • fastDOOM mengeksplorasi berbagai optimasi untuk beragam kombinasi CPU dan bus video seperti 386, 486, Pentium, Cyrix serta ISA, VLB, dan PCI
  • Pada IBM PS/1 486-DX2 66MHz, optimasi yang memakai Mode 13h alih-alih Mode Y justru lebih lambat
  • Mode 13h

    • Hardware menangani distribusi data ke empat VRAM bank VGA, sehingga bagi CPU terlihat seperti satu framebuffer linear 320x200
    • Karena double buffering tidak bisa dilakukan di VRAM, buffering harus dilakukan di RAM lalu disalin kembali ke VRAM, sehingga byte ditulis dua kali
    • Engine harus diblokir pada VSYNC
  • Mode Y

    • VGA bank bisa diakses satu per satu, memungkinkan VRAM triple buffering, dan byte bisa ditulis langsung ke VRAM sekali saja
    • Pemilihan bank membutuhkan instruksi OUT yang lambat
    • Jika menulis ke dua VGA bank sekaligus lewat latch, replikasi piksel horizontal memungkinkan low-detail mode
    • Rendering Specter yang invisible membutuhkan VRAM readback, sehingga jauh lebih lambat
    • Menurut penjelasan John Carmack, DOOM menggunakan mode interleaved planar yang mirip Mode X pada mode VGA 320×200×256, dan merotasi tiga display page
    • Texture mapping langsung ke video memory bisa memberi tambahan kecepatan 10%~15% pada banyak kartu video
    • Page flip tanpa tearing juga bisa dilakukan dibanding buffering di main memory
    • Heretic dirilis pada 1994, dan karena perubahan hardware pada masa itu membuat Mode 13h menjadi pilihan yang lebih menarik, Raven memodifikasi engine DOOM ke arah ini
    • fastDOOM menyediakan beberapa executable bagi pengguna
    • FDOOM.EXE
    • FDOOM13H.EXE
    • FDOOMVBD.EXE
  • Mode 13h dan VESA direct di fastDOOM

    • Mode 13h fastDOOM merender ke satu framebuffer di RAM, lalu menyalinnya ke VRAM setelah seluruh scene selesai
    • Karena tidak memaksa VSYNC, flickering bisa terjadi
    • Pada bus ISA 8-bit yang lambat, differential copy digunakan untuk mengirim hanya piksel yang berubah
    • Pada bus yang lebih cepat seperti ISA 16-bit, VLB, dan PCI, seluruh backbuffer disalin dengan REP MOVS
    • Berdasarkan pengujian Viti95, mode terbaik untuk CPU 486 adalah FDOOMVBD.EXE, yaitu VESA direct mode untuk 320×200
      • Menggabungkan keunggulan Mode Y dan kode rendering Heretic yang sudah dioptimasi
      • Menghindari instruksi OUT, kecuali satu OUT per frame saat berpindah buffer
      • Membutuhkan kartu grafis VLB atau PCI dengan LFB aktif dan dukungan VESA 2.0, serta lambat pada low-detail dan potato-detail mode
    • IBM 2168 tidak mendukung VESA 2.0, sehingga FDOOMVBP.EXE dan FDOOMVBD menghasilkan error saat dijalankan

Percobaan yang Tidak Berhasil dan Kesan Keseluruhan

  • Flag spesifik prosesor OpenWatcom, yaitu 4r/4s dan 3r/3s, juga dicoba tetapi dihentikan
    • Flag 386 dan 486 pada wcc386 sama-sama dicoba, dan pada akhirnya versi 386 selalu tampak lebih cepat
  • Viti95 juga punya tujuan mengganti compiler fastDOOM dari OpenWatcom v2 ke DJGPP, yaitu GCC
    • Sebab, dari source yang sama, GCC terlihat menghasilkan kode yang lebih cepat
    • Atau, peningkatan OpenWatcom v2 agar memperkecil selisih performa juga tetap menjadi opsi yang diinginkan
  • Performa fastDOOM adalah hasil dari memanfaatkan peningkatan yang sudah ada dari Crispy, PSX, GBA, dan Lee Killough, lalu menambahkan banyak optimasi baru
  • Ide dan sebagian kode Ken Silverman juga masuk ke fungsi rendering untuk UMC Green CPU, menghasilkan peningkatan kecepatan besar pada hardware tersebut
  • fastDOOM bukan satu perubahan ajaib, melainkan contoh port DOS yang menjadi lebih cepat daripada DOOM asli berkat akumulasi ribuan optimasi kecil

1 komentar

 
GN⁺ 2025-03-05
Komentar Hacker News
  • Ini contoh bagus bahwa bottleneck biasanya tidak berada di tempat yang kita duga, jadi profiling dan pengukuran itu diperlukan
    Ternyata rendering persentase di status bar; bagi pakar yang sangat memahami struktur Doom mungkin ini relatif jelas, tetapi sebelumnya rasanya mustahil menebaknya sebagai bottleneck

    • Misalnya, ada kasus sebuah aplikasi tanpa sebab jelas memakai CPU 60% dan GPU 25%, dan ternyata penyebabnya adalah animasi CSS kecil
      https://www.granola.ai/blog/dont-animate-height
    • Ini mengingatkan pada kasus optimasi di Super Mario World untuk SNES, ketika tampilan skor pemain sangat tidak efisien sampai memakan sekitar 1/6 waktu frame
      Dalam skenario terburuk, menampilkan skor di status bar memakai hampir 1/6 dari seluruh frame sehingga ambang terjadinya perlambatan menjadi lebih rendah, dan patch-nya mengubah cara penyimpanan serta penampilan skor menjadi hampir constant time, bahkan sedikit lebih cepat daripada kasus terbaik sebelumnya
      https://www.smwcentral.net/?p=section&a=details&id=35746
    • Dari sudut pandang developer game, perlambatan seperti ini umum terjadi
      Rendering UI bisa menjadi fatal karena transparansi, layering, redraw, terutama karena memicu alokasi memori, dan cara membandingkan nilai lama dengan nilai baru sebelum redraw sangat membantu
      Di CSS juga pernah ada proyek yang bottleneck-nya adalah layer dan transparansi, dan saat itu kuncinya adalah mengurangi jumlah layer
    • Contoh favorit saya adalah masalah waktu loading GTA Online, yang akhirnya disebabkan oleh pemrosesan file JSON 10MB yang keliru dan dilacak oleh orang dari luar organisasi
      Loading 6 menit berhasil dipangkas menjadi kurang dari 2 menit
      https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
    • Ini mengingatkan pada kejadian npm yang menjadi 2 kali lebih lambat dari seharusnya karena progress bar terminal yang mewah
      https://news.ycombinator.com/item?id=10974929
  • Mungkin saya bukan target pembaca sebenarnya, tetapi NETDRIVE dari mTCP menarik
    Saya tidak menyangka sudah ada opsi network storage yang cukup layak pada masa setua itu, lalu setelah mencari, saya menemukan https://www.brutman.com/mTCP/mTCP_NetDrive.html, dan itu keren sekali
    Katanya NetDrive adalah device driver yang memungkinkan image disk jarak jauh yang di-host oleh mesin lain diakses di DOS seperti perangkat lokal yang terpasang sebagai drive letter

    • Di lab komputer sekolah pada awal 90-an, sekitar 25 Mac Plus terhubung secara daisy-chain ke Mac II dengan AppleTalk, dan semua Plus me-mount filesystem dari Mac II
      Sangat lambat, sampai para siswa membuang 5–10 menit di awal kelas hanya untuk membuka word processor, dan Xerox Alto juga memakai network mount untuk drive
      Kalau ada networking, cepat atau lambat seseorang akan ingin menyalin file, dan cara paling nyaman adalah membuatnya terlihat seperti filesystem lokal
      DOS tidak punya networking bawaan, jadi tertinggal dalam hal ini dan banyak hal harus dilakukan sendiri
    • Ada trik rapi untuk network boot DOS dari target iSCSI dengan iPXE
      Ini memungkinkan akses baca-tulis ke network block device tanpa driver atau konfigurasi di sisi DOS, tetapi kalau dipakai seperti share akan cepat rusak dan sifatnya lebih mirip block device
      Terasa seperti sihir, tetapi sepertinya iPXE mem-patch BIOS agar akses disk dikirim ke iSCSI
    • Saya penasaran apakah pada era DOS juga ada NAS atau mount WebDAV
      FTP dan telnet tentu saja ada, tetapi saya penasaran apakah remote mount benar-benar digunakan atau mustahil karena bandwidth yang rendah
  • Thread GitHub yang melibatkan Ken Silverman terasa seperti harta karun
    Menakjubkan melihat penulis FastDOOM dan Ken menggali register 486 dan efisiensi clock cycle yang rumit
    Senang melihat masih ada orang yang memastikan Doom terus mendapat peningkatan performa

    • Saya jadi teringat KenS setelah benar-benar lama; pada era 90-an ia sangat aktif di kancah modding Duke3D
      Scripting itu secara harfiah adalah “coding” pertama saya, dan dalam arti tertentu, seluruh karier serta aset saya bisa dibilang saya berutang kepada KenS, jadi itu keren
    • Tahun lalu, ketika membuat engine rendering 2.5D yang mirip, saya mengirim email kepada Ken Silverman tentang bagian Build Engine yang kurang dikenal, dan ia membalas seolah-olah baru kemarin mengerjakannya
    • Di dalamnya ada konten yang benar-benar seperti permata
      Saya terutama suka ide memakai CR2 dan CR3 sebagai register scratchpad pada 386SX dan 386DX tanpa cache, ketika akses memori sangat lambat
      Teknik memakai ESP sebagai loop counter tanpa mematikan interrupt juga jenius, dengan cara memastikan ia selalu menunjuk ke posisi stack yang valid
  • Fitur FastDOOM yang tidak banyak dibahas di sini adalah segala macam mode video yang aneh
    Mode teks IBM MDA: https://www.youtube.com/watch?v=Op2tr2lGK6Y
    EGA & Plantronics ColorPlus: https://www.youtube.com/watch?v=gxx6lJvrITk
    CGA biru-merah muda klasik: https://youtu.be/rD0UteHi2qM
    CGA 320x200x16 yang memakai hack ‘ANSI from Hell’: https://www.youtube.com/watch?v=ut0V1nGcTf8
    Hercules: https://www.youtube.com/watch?v=EEumutuyBBo
    Sebagian besar tampaknya berjalan lebih lambat daripada VGA karena pekerjaan seperti remapping warna

    • Akan bagus juga kalau Tandy Graphics Adapter didukung
      Kalau harus menjalankannya dengan CGA, rasanya saya tidak akan suka; dan kalau masih hidup, sepertinya akan butuh build 286 untuk Tandy 1000 TL/2
    • Benar-benar keren, dan menunjukkan dengan baik mengapa aspek-aspek semacam ini dalam game perlu dipisahkan
      Saya jadi teringat Clean Architecture yang “modern” pada aplikasi backend
    • Mode teks IBM MDA itu mengerikan... makanya bagus
  • Bagian “IBM PS/1 486-DX2 66Mhz, ‘Mini-Tower’, model 2168. Komputer yang selalu saya inginkan saat remaja tetapi tidak mampu saya beli” terasa berkesan
    Sekitar 1992 saya memakai PC rakitan sendiri yang keempat, dan menurut saya pameran komputer KCS di Marlborough MA adalah sumber daya luar biasa bagi para tukang oprek
    Polanya membeli komponen, merakit PC, memakainya beberapa waktu lalu menjualnya, kemudian membeli komponen lagi
    Pada akhir 1992 saya menjalankan 486-DX3 100 dengan koprosesor matematika ULSI 487, dan selama beberapa waktu bisa dibilang itu PC tercepat di kampus, mungkin bahkan komputer tercepat
    Lebih cepat daripada beberapa model Pentium dan tidak menghasilkan kesalahan matematika
    Build terakhir saya justifikasi karena waktu kalkulasi ulang terlalu lama saat mensimulasikan pembangkit kogenerasi gas/diesel dalam spreadsheet Excel 21 halaman untuk tesis kehormatan
    Jurusan saya ilmu lingkungan, tetapi seluruh karier saya akhirnya di komputer

    • Entah apakah ini pantas disebut “wow”
      Apakah perlu membuat orang yang tidak mampu membeli komputer seperti itu pada 1992 merasa susah?
      Selain itu tidak ada yang namanya “DX3”, dan DX4, 486 100MHz pertama, keluar pada Maret 1994, jadi klaim menjalankannya pada akhir 1992 tampaknya tidak benar
      Komputer pertama di rumah kami, selain XT yang kami terima sekitar 1992 dan sudah terlalu usang, adalah 66MHz 486-DX2 yang dibeli awal 1995
      Bahkan puluhan tahun kemudian, melihat orang anehnya membanggakan komputer mustahil yang lebih cepat daripada komputer saya meski punya handicap 3 tahun, tetap membuat harga diri saya agak tersinggung
    • Jelas membangkitkan kenangan
      Sekitar 1992 saya mahasiswa miskin, dan meminjam sekitar 2.000 dolar dari credit union untuk membeli 486 DX2-50
      Dalam uang sekarang, itu berarti menghabiskan lebih dari 4.000 dolar untuk komputer yang cukup dasar, dan saya dual boot DOS dan Linux di mesin itu
    • 487 di 486DX, ya? Saya kira 487 hanya berguna untuk chip SX
      Setelah mencari, ternyata 487 standar pada dasarnya adalah 486DX lengkap yang menonaktifkan dan menggantikan 486SX
      Mungkinkah itu koprosesor lain yang hebat yang tidak saya ketahui?
    • Kalau “lebih cepat daripada beberapa model Pentium dan tidak menghasilkan kesalahan matematika”, itu benar-benar bahan pamer
      Benar-benar mengungguli dengan telak
  • Selain sering merilis, Viti95 menunjukkan disiplin Git yang luar biasa: satu commit melakukan satu hal dan setiap rilis diberi tag
    https://fabiensanglard.net/fastdoom/#:~:text=one%20commit%20...

  • Saya tidak mengerti maksud Ibuprofen dalam kalimat “sampai mengenal fastDOOM, saya sudah pasrah harus bermain sambil minum Ibuprofen”

    • Mungkin maksudnya sakit kepala akibat frame rate rendah
  • Kalau penulis melihat ini, di seluruh dokumen nama belakang John Carmack salah ketik menjadi “Carnmack”

  • Jika melihat secara tidak sinis alasan perangkat lunak modern lambat dan optimasi semacam ini tidak dilakukan, hal itu bisa dijelaskan dengan hipotesis standardisasi/optimasi
    Ketika sesuatu menjadi standar, optimasi akan menyusul
    Karena orang ingin menjadi yang tercepat sambil tetap lulus semua pengujian standar
    Doom kini juga sudah menjadi game standar yang di-porting ke mana saja, entah CPU baru atau toaster, dan protokol email maupun standar browser seperti WebRTC, QUIC, dan sebagainya juga serupa
    Alasan aplikasi web modern atau aplikasi Electron tidak cepat adalah karena mereka masih berada di tahap eksplorasi
    Mereka diperbarui setiap hari untuk memenuhi kebutuhan pengguna baru, dan dari sisi performa, cukup asal cukup cepat agar tidak mengganggu
    Karena itu aplikasi IRC sangat cepat, tetapi Slack dan Teams memang akan selalu lambat

  • Menelusuri mundur versi untuk memeriksa perbaikan dan regresi bukan hal sepele
    Sebagian optimasi bisa menciptakan bug yang baru ditemukan belakangan, dan fitur yang benar-benar diperlukan juga bisa menurunkan performa
    Jadi hidup akan lebih mudah jika ada pengujian performa yang berjalan otomatis sebelum setiap rilis, dan ketika masalah performa ditemukan, tulis saja regression test seperti biasa
    Intinya, yang ingin saya katakan adalah lakukan pengujian performa