Mengapa fastDOOM Begitu Cepat
(fabiensanglard.net)- 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 demo1di IBM PS/1 486-DX2 66MHz model “Mini-Tower” 2168, hasilnya1710 gametics in 2783 realtics- DOOM tidak menampilkan fps secara langsung, sehingga harus dihitung dengan
1710/2783*35; hasilnya 21,5fps
- DOOM tidak menampilkan fps secara langsung, sehingga harus dihitung dengan
- Di mesin yang sama, menjalankan
fdoom.exe -timedemo demo1menghasilkan1710 gametics in 1988 realtics, yaitu 30,1fps - Pada map yang lebih berat seperti
demo1didoom2, 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.cyang direkayasa balik dari reverse assemblyDOOM.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.EXEasli diunduh, lalu program Go digunakan untuk membuatRUN.BATyang menjalankan-timedemo demo1; semuanya di-mount dengan mTCPNETDRIVEuntuk pengujian- Kondisinya adalah
DOOM.WAD, sound on, screen size 10 - Seluruh suite dijalankan 5 kali dan fps rata-ratanya digambarkan dalam grafik
- Kondisinya adalah
- PCDOOM v2 dibangun dengan OpenWatcom 2, tetapi peningkatannya dibanding
DOOM.EXEasli 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
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, danv0.9.7, yang peningkatan kecepatannya besar -
fastDOOM v0.1
v0.1terdiri 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
FixedDivsebagai 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
-
fastDOOM v0.8
v0.8terdiri 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
-
fastDOOM v0.9.2 dan v0.9.7
v0.9.2terdiri dari 110 commit, dengan perubahan utama berupa optimasi perbandingan skyflatnum, optimasiR_DrawColumnuntuk Mode Y, dan perapian kodeR_DrawSpanv0.9.7diperkenalkan 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
OUTyang 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.EXEFDOOM13H.EXEFDOOMVBD.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 satuOUTper 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.EXEdanFDOOMVBDmenghasilkan error saat dijalankan
Percobaan yang Tidak Berhasil dan Kesan Keseluruhan
- Flag spesifik prosesor OpenWatcom, yaitu
4r/4sdan3r/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
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
https://www.granola.ai/blog/dont-animate-height
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
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
Loading 6 menit berhasil dipangkas menjadi kurang dari 2 menit
https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
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
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
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
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
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
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
Kalau harus menjalankannya dengan CGA, rasanya saya tidak akan suka; dan kalau masih hidup, sepertinya akan butuh build 286 untuk Tandy 1000 TL/2
Saya jadi teringat Clean Architecture yang “modern” pada aplikasi backend
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
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
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
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?
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”
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