1 पॉइंट द्वारा GN⁺ 2025-03-05 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 1993 के high-performance PC-क्लास IBM PS/1 486-DX2 66MHz पर original DOOM demo1 के आधार पर 21.5fps था, जबकि fastDOOM समान शर्तों में 30.1fps तक पहुंचा, जो DOS port optimization का अंतर दिखाता है
  • fastDOOM की शुरुआत PCDOOM v2 से हुई, जिसमें Linux DOOM core, Heretic I/O, APODMX और DOOM.EXE disassembly पर आधारित Mode Y graphics I/O को जोड़ा गया था
  • 52 releases और 3,042 commits को build व benchmark करने पर पता चला कि performance gain किसी एक modern compiler से नहीं, बल्कि छोटे optimizations के accumulated effect से आया
  • बड़े improvements में status bar rendering skip करना, FixedDiv को inline करना, BSP traversal optimization, visplane rendering skip करना, pointer indirect reference हटाना, और renderer-specific executables को अलग करना शामिल था
  • Graphics mode में फायदा/नुकसान CPU और bus पर निर्भर करता है; धीमे CPU में Mode Y बेहतर है, और तेज़ CPU व VLB/PCI environment में Mode 13h या VESA direct बेहतर हो सकते हैं, लेकिन VESA 2.0 जैसी constraints बची रहती हैं

486-DX2 पर दिखा performance gap

  • IBM PS/1 486-DX2 66MHz “Mini-Tower” model 2168 पर original DOOM को doom.exe -timedemo demo1 से चलाने पर 1710 gametics in 2783 realtics मिलता है
    • DOOM सीधे fps output नहीं करता, इसलिए 1710/2783*35 से calculate करना पड़ता है; result 21.5fps है
  • उसी machine पर fdoom.exe -timedemo demo1 चलाने पर 1710 gametics in 1988 realtics, यानी 30.1fps confirm होता है
  • doom2 के demo1 जैसे ज्यादा heavy map में original 16.8fps से fastDOOM 24.9fps तक पहुंचता है, यानी 48% तेज़
  • हालांकि joystick और network gameplay support हटा दिया गया है, इसलिए यह ऐसा port नहीं है जो सभी features को ज्यों का त्यों preserve करता हो

fastDOOM की code lineage

  • DOOM मूल रूप से NeXT Workstation पर develop किया गया था, और यह ज्यादातर core code व छोटे I/O subsystem में बंटा था, जिससे इसकी porting-friendly structure बनी
  • Commercial DOS version ने id Software द्वारा लिखा गया DOS I/O इस्तेमाल किया, लेकिन proprietary sound library DMX dependency के कारण 1997 में उसे वैसा का वैसा open source नहीं किया जा सका
  • Public किया गया code Bernd Kreimeier द्वारा engine explanation book project के दौरान整理 किया गया Linux version था
  • DOS version PCDOOM v2 को इस combination से reconstruct किया गया
    • Linux DOOM का core
    • Heretic का I/O
    • DMX की नकल करने के लिए APODMX
    • DOOM.EXE disassembly से reverse-engineered i_ibm.c graphics I/O
  • fastDOOM ने इसी PCDOOM v2 को starting point बनाया

Releases और commits से track किया गया performance change

  • Victor “Viti95” Nieto ने fastDOOM को frequent releases दिए और हर release को tag किया, साथ ही एक commit को एक काम तक सीमित रखने का discipline रखा
  • fastDOOM का Git history 3,042 commits से बना है, जिससे commit-by-commit performance changes track किए जा सके
  • 52 fastDOOM releases, PCDOOM v2 और original DOOM.EXE download करके -timedemo demo1 चलाने वाला RUN.BAT Go program से generate किया गया, और mTCP NETDRIVE से mount करके test किया गया
    • Conditions थीं DOOM.WAD, sound on, screen size 10
    • पूरी suite को 5 बार run करके average fps को graph में plot किया गया
  • PCDOOM v2 OpenWatcom 2 से build होने के बावजूद original DOOM.EXE की तुलना में बड़ा improvement नहीं दिखाता, इसलिए fastDOOM का gain सिर्फ modern compiler usage से समझाना मुश्किल है
  • File size graph में शुरुआती काम code cleanup और deletion के जरिए उसे हल्का बनाने की दिशा में था
    • bf0e983: sound recording हटाया गया
    • 5f38323: error code strings delete किए गए
    • 8b9cac5: TASM को NASM से replace किया गया

Performance बढ़ाने वाले release-wise changes

  • सभी 3,042 builds को timedemo करने में करीब 9 दिन लग सकते थे, इसलिए जिनमें speed gains बड़े थे, उन v0.1, v0.6, v0.8, v0.9.2, v0.9.7 पर focused commit-level benchmarking की गई
  • fastDOOM v0.1

    • v0.1 220 commits से बना है
    • सबसे बड़ा patch build 36 का e16bab8 है
      • “Crispy optimization” status bar percentage नहीं बदलने पर rendering को no-op बना देता है, जिससे scrap buffer rendering और screen blit बचते हैं
      • सिर्फ इस change से 2fps की बढ़ोतरी confirm हुई
    • build 167 के a9359d5 ने FixedDiv को macro के रूप में inline किया
    • build 207 के 9bd3f20 ने PSX Doom optimization लाकर BSP traversal method सुधारा
    • build 212 के dc0f48e ने horizontal surface rendering function R_MakeSpans को inline किया
    • कुल commits में deletion commits 100 थे, यानी करीब आधे code deletion थे
  • fastDOOM v0.6

    • v0.6 33 commits से बना है
    • build 342 के 22819fd ने unnecessary visplane rendering skip किया
    • build 359 के 40e0d4b और build 360 के ccd296f ने player pointer indirect references घटाए
    • build 369 के f29e665 ने screenspace line splitter को inline किया
  • fastDOOM v0.8

    • v0.8 282 commits से बना है
    • sound system unstable था, इसलिए timedemo बिना sound के चलाकर fps adjust किया गया
    • यह release text-mode renderer पर focused था, और build 670 व build 730 में Crispy optimization हटने से regression आया
    • मुख्य improvements इस प्रकार हैं
      • f279b7d: FDOOM.EXE, FDOOM13H.EXE आदि renderer-specific executables को अलग किया गया
      • 1874ee8: compiler debugging disable की गई
      • 6aae724: Crispy optimization restore किया गया
      • 1366ebf: जहां संभव हो, कम code ही compile किया गया
  • fastDOOM v0.9.2 और v0.9.7

    • v0.9.2 110 commits वाला है; skyflatnum comparison optimization, Mode Y के लिए R_DrawColumn optimization, और R_DrawSpan code cleanup इसके मुख्य changes हैं
    • v0.9.7 को 293 commits के रूप में introduce किया गया, लेकिन command output 294 दिखाता है
    • इस release में कई बार benchmark करने पर भी noise कम नहीं हो सका
    • मुख्य changes में x86 ASM change tests, 386SX के लिए CPU selection और CR2 optimization, R_DrawSpan386SX के लिए ESP optimization, ASM fuzz column rendering-based code, और per-loop CMP comparison हटाना शामिल हैं

Mode 13h, Mode Y, VESA direct चुनने के criteria

  • fastDOOM 386, 486, Pentium, Cyrix और ISA, VLB, PCI जैसी अलग-अलग CPU-video bus combinations के लिए कई optimizations explore करता है
  • IBM PS/1 486-DX2 66MHz पर Mode Y के बजाय Mode 13h इस्तेमाल करने वाला optimization धीमा था
  • Mode 13h

    • VGA के चार VRAM banks में data distribute करने का काम hardware करता है, इसलिए CPU को यह single linear 320x200 framebuffer जैसा दिखता है
    • VRAM में double buffering नहीं की जा सकती, इसलिए RAM में buffering करने के बाद उसे फिर VRAM में copy करना पड़ता है, यानी bytes दो बार लिखे जाते हैं
    • Engine को VSYNC पर block होना पड़ता है
  • Mode Y

    • VGA banks को individually access किया जा सकता है, जिससे VRAM triple buffering संभव है, और bytes सीधे VRAM में सिर्फ एक बार लिखे जा सकते हैं
    • Bank selection के लिए धीमा OUT command चाहिए
    • latch के जरिए दो VGA banks में simultaneously लिखने पर horizontal pixel replication संभव है, जिससे low-detail mode मिलता है
    • invisible Specter rendering को VRAM readback चाहिए, इसलिए यह काफी धीमा है
    • John Carmack के explanation के अनुसार DOOM ने 320×200×256 VGA mode में Mode X जैसा interleaved planar mode इस्तेमाल किया और तीन display pages को rotate किया
    • video memory में directly texture mapping करने से कई video cards पर 10%~15% extra speed मिल सकती थी
    • main memory buffering की तुलना में tearing-free page flip भी संभव था
    • Heretic 1994 में release हुआ, और उस समय hardware changes के कारण Mode 13h ज्यादा attractive choice बन गया, इसलिए Raven ने DOOM engine को इसी दिशा में modify किया
    • fastDOOM users को कई executables देता है
    • FDOOM.EXE
    • FDOOM13H.EXE
    • FDOOMVBD.EXE
  • fastDOOM का Mode 13h और VESA direct

    • fastDOOM का Mode 13h RAM के single framebuffer में render करता है और पूरा scene खत्म होने पर उसे VRAM में copy करता है
    • VSYNC force नहीं करता, जिससे flickering हो सकती है
    • धीमे 8-bit ISA bus पर सिर्फ बदले हुए pixels भेजने वाली differential copy इस्तेमाल होती है
    • 16-bit ISA, VLB, PCI जैसे तेज़ bus पर REP MOVS से पूरा backbuffer copy किया जाता है
    • Viti95 के tests के अनुसार 486 CPU के लिए सबसे अच्छा mode 320×200 के लिए VESA direct mode FDOOMVBD.EXE है
      • यह Mode Y के advantages और Heretic के optimized rendering code को combine करता है
      • Buffer switch करते समय प्रति frame एक OUT को छोड़कर OUT commands से बचता है
      • LFB enabled VLB या PCI graphics card और VESA 2.0 support चाहिए, और low-detail व potato-detail mode में धीमा है
    • IBM 2168 VESA 2.0 support नहीं करता, इसलिए FDOOMVBP.EXE और FDOOMVBD चलाने पर error आता है

जो कोशिशें काम नहीं आईं और overall impression

  • OpenWatcom के processor-specific flags 4r/4s और 3r/3s भी try किए गए, लेकिन बंद कर दिए गए
    • wcc386 के 386 flags और 486 flags दोनों try किए गए, और नतीजे में 386 version हमेशा तेज़ दिखा
  • Viti95 का लक्ष्य fastDOOM के compiler को OpenWatcom v2 से DJGPP, यानी GCC, में बदलना भी है
    • क्योंकि उसी source से GCC तेज़ code generate करता दिखा
    • या OpenWatcom v2 का performance gap घटाने के लिए improve होना भी एक desirable option बना हुआ है
  • fastDOOM की performance Crispy, PSX, GBA, Lee Killough के existing improvements का उपयोग करने और बड़ी मात्रा में नए optimizations जोड़ने का result है
  • Ken Silverman के ideas और code के कुछ हिस्से भी UMC Green CPU के rendering functions में गए, जिससे उस hardware पर बड़ा speed gain मिला
  • fastDOOM कोई एक जादुई बदलाव नहीं, बल्कि हजारों छोटे optimizations के जमा होने से original DOOM से तेज़ बना DOS port है

1 टिप्पणियां

 
GN⁺ 2025-03-05
Hacker News टिप्पणियां
  • यह इस बात का अच्छा उदाहरण है कि bottleneck आम तौर पर वहां नहीं होता जहां आप उम्मीद करते हैं, इसलिए profiling और measurement ज़रूरी हैं
    status bar में percentage rendering—Doom की संरचना को अच्छी तरह जानने वाले विशेषज्ञ के लिए शायद यह अपेक्षाकृत स्पष्ट रहा हो, लेकिन पहले से इसे bottleneck मानना बिल्कुल मुश्किल लगता

    • उदाहरण के लिए, एक मामला था जहां एक app बिना साफ वजह के CPU 60% और GPU 25% इस्तेमाल कर रहा था, और बाद में पता चला कि वजह एक छोटा CSS animation था
      https://www.granola.ai/blog/dont-animate-height
    • SNES के लिए Super Mario World में भी player score display बहुत inefficient था और frame time का करीब 1/6 खा जाता था—ऐसा optimization case याद आता है
      सबसे खराब स्थिति में status bar पर score दिखाने में पूरे frame का लगभग 1/6 लग जाता था, जिससे slow होने की threshold कम हो गई थी; patch ने score को store और display करने का तरीका लगभग constant time जैसा बना दिया, और इसे पुराने best case से भी थोड़ा तेज़ कर दिया
      https://www.smwcentral.net/?p=section&a=details&id=35746
    • game developer के नजरिए से ऐसी slowdown आम है
      transparency, layering, redraw, खासकर memory allocation trigger होने की वजह से UI rendering घातक हो सकती है, और redraw से पहले पुराने और नए value की तुलना करना काफी मदद करता है
      CSS में भी एक project में layers और transparency bottleneck थे, और तब मुख्य बात layer count कम करना था
    • मेरा पसंदीदा उदाहरण GTA Online loading time की समस्या है, जो आखिरकार 10MB JSON file को गलत तरीके से process करने की वजह से थी, और संगठन के बाहर के व्यक्ति ने इसे trace किया
      6 मिनट की loading को 2 मिनट से कम कर दिया गया
      https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times...
    • npm के उस मामले की याद आती है जब चमकदार terminal progress bar की वजह से वह असल में 2 गुना धीमा था
      https://news.ycombinator.com/item?id=10974929
  • शायद मैं इसका वास्तविक target audience नहीं हूं, लेकिन mTCP का NETDRIVE दिलचस्प लगा
    मुझे नहीं पता था कि इतने पुराने समय में भी इस्तेमाल लायक network storage options रहे होंगे, लेकिन खोजने पर https://www.brutman.com/mTCP/mTCP_NetDrive.html मिला, जो सच में शानदार है
    कहा जाता है कि NetDrive एक device driver है जो किसी दूसरी machine द्वारा host की गई remote disk image को DOS में drive letter से जुड़े local device की तरह access करने देता है

    • 90s की शुरुआत में स्कूल के computer lab में करीब 25 Mac Plus AppleTalk के जरिए Mac II से daisy-chain जुड़े थे, और सभी Plus, Mac II से filesystem mount करते थे
      यह बेहद धीमा था, इसलिए students class की शुरुआत में word processor खोलने में 5–10 मिनट गंवा देते थे, और Xerox Alto भी drives के लिए network mounts इस्तेमाल करता था
      अगर networking है तो कोई न कोई जल्द ही files copy करना चाहेगा, और सबसे आसान तरीका है उसे local filesystem जैसा दिखाना
      DOS में built-in networking नहीं थी, इसलिए वह इस मामले में पीछे था और काफी कुछ खुद करना पड़ता था
    • iPXE के जरिए iSCSI target से DOS को network boot करने की एक साफ-सुथरी trick है
      DOS-side driver या configuration के बिना network block device पर read/write access मिल जाता है, लेकिन इसे share की तरह इस्तेमाल करें तो यह जल्दी टूट जाता है और block device के ज्यादा करीब है
      यह जादू जैसा लगता है, लेकिन शायद iPXE BIOS को patch करके disk access को iSCSI पर भेजता है
    • सोचता हूं कि DOS के दौर में NAS या WebDAV mount होते थे या नहीं
      FTP और telnet जैसी चीजें तो जाहिर है रही होंगी, लेकिन remote mount सच में इस्तेमाल होते थे या कम bandwidth की वजह से असंभव थे—यह जानने की जिज्ञासा है
  • Ken Silverman वाला GitHub thread किसी खजाने जैसा है
    FastDOOM के author और Ken को मुश्किल 486 registers और clock cycle efficiency में गहराई तक जाते देखना कमाल है
    अच्छा लगता है कि कोई अब भी Doom की performance improvements का ध्यान रख रहा है

    • KenS को सच में बहुत लंबे समय बाद याद किया; 90s में वे Duke3D modding scene में काफी active थे
      वह scripting सचमुच मेरी पहली “coding” थी, और एक तरह से मैं अपना career और पूरी संपत्ति KenS का ऋणी मानता हूं—यह शानदार है
    • पिछले साल ऐसा ही एक 2.5D rendering engine बनाते समय मैंने Build Engine के एक कम जाने-पहचाने हिस्से के बारे में Ken Silverman को email भेजा था, और उन्होंने ऐसे जवाब दिया जैसे कल ही उस पर काम कर रहे हों
    • उसमें सचमुच रत्न जैसी बातें हैं
      खासकर memory access बहुत धीमा होने वाले 386SX और cache-less 386DX पर CR2 और CR3 को scratchpad registers की तरह इस्तेमाल करने का idea अच्छा लगा
      interrupts बंद किए बिना ESP को loop counter की तरह इस्तेमाल करने की technique भी genius है, जिसमें यह सुनिश्चित किया जाता है कि वह हमेशा valid stack location की ओर ही point करे
  • FastDOOM में यहाँ जिस feature पर ज़्यादा बात नहीं हुई, वह है हर तरह के अजीब video modes
    IBM MDA text mode: https://www.youtube.com/watch?v=Op2tr2lGK6Y
    EGA & Plantronics ColorPlus: https://www.youtube.com/watch?v=gxx6lJvrITk
    क्लासिक नीला-गुलाबी CGA: https://youtu.be/rD0UteHi2qM
    ‘ANSI from Hell’ hack इस्तेमाल करने वाला CGA 320x200x16: https://www.youtube.com/watch?v=ut0V1nGcTf8
    Hercules: https://www.youtube.com/watch?v=EEumutuyBBo
    लगता है ज़्यादातर VGA से भी धीमे चलते हैं, शायद color remapping जैसे कामों की वजह से

    • Tandy Graphics Adapter को भी support मिल जाए तो अच्छा होगा
      अगर CGA पर चलाना पड़े तो मुझे पसंद नहीं आएगा, और अगर वह अभी भी ज़िंदा होता तो शायद Tandy 1000 TL/2 के लिए 286 build चाहिए होता
    • सच में कमाल है, और यह अच्छी तरह दिखाता है कि game के ऐसे पहलुओं को अलग क्यों रखा जाना चाहिए
      backend applications की “modern” Clean Architecture याद आती है
    • IBM MDA text mode भयावह है... इसलिए अच्छा है
  • “IBM PS/1 486-DX2 66Mhz, ‘Mini-Tower’, model 2168. किशोर उम्र में जिस computer को मैं हमेशा चाहता था, लेकिन खरीद नहीं सकता था” वाला हिस्सा प्रभावशाली लगा
    1992 के आसपास मैं अपना खुद assembled चौथा PC इस्तेमाल कर रहा था, और Marlborough MA का KCS computer show tinkerers के लिए जबरदस्त resource था
    parts खरीदकर PC बनाता, कुछ समय इस्तेमाल करता, फिर बेच देता, और फिर parts खरीदता था
    1992 के अंत तक मैं ULSI 487 math coprocessor लगे 486-DX3 100 पर चल रहा था, और कुछ समय तक वह campus का सबसे तेज़ PC, शायद सबसे तेज़ computer भी कहा जा सकता था
    वह कई Pentium models से तेज़ था और math errors भी नहीं देता था
    आख़िरी build को मैंने अपनी honours thesis के लिए justify किया था, क्योंकि gas/diesel cogeneration plant को 21-page Excel spreadsheet में simulate करने पर recalculation time बहुत लंबा हो रहा था
    major Environmental Science था, लेकिन career पूरी तरह computers में चला गया

    • समझ नहीं आता कि इस पर “wow” कहना चाहिए या नहीं
      क्या 1992 में ऐसा computer afford न कर पाने वाले व्यक्ति को यूँ चुभाना ज़रूरी था
      ऊपर से “DX3” नाम की कोई चीज़ नहीं थी, और पहला 100MHz 486 यानी DX4 मार्च 1994 में आया, इसलिए 1992 के अंत में इसे चलाने की बात सही नहीं लगती
      हमारे घर का पहला computer, 1992 के आसपास मिले पहले से ही बहुत पुराने XT को छोड़ दें, तो 1995 की शुरुआत में खरीदा गया 66MHz 486-DX2 था
      दशकों बाद भी, 3 साल का handicap होने के बावजूद मेरे computer से तेज़ बताई जा रही उस असंभव machine की अजीब शेख़ी देखकर बेवजह अहं को ठेस लगती है
    • सच में यादें ताज़ा हो जाती हैं
      1992 के आसपास मैं गरीब college student था और credit union से करीब 2,000 dollars loan लेकर 486 DX2-50 खरीदा था
      आज के पैसों में देखें तो एक काफ़ी basic computer पर 4,000 dollars से ज़्यादा खर्च किए थे, और उस पर DOS और Linux dual boot करता था
    • 486DX में 487? मुझे लगा था 487 सिर्फ SX chips के लिए उपयोगी था
      खोजने पर पता चला कि standard 487 असल में पूरा 486DX था, जो मूल 486SX को disable करके replace करता था
      क्या यह कोई और शानदार coprocessor था जिसके बारे में मुझे पता नहीं था
    • “कई Pentium models से तेज़ था और math errors भी नहीं देता था” तो यह पूरी तरह bragging rights वाली बात है
      उसने ठीक से धूल चटा दी थी
  • बार-बार releases करने के अलावा, Viti95 ने बेहतरीन Git discipline दिखाया: एक commit एक काम करता है और हर release को tag किया गया था
    https://fabiensanglard.net/fastdoom/#:~:text=one%20commit%20...

  • “fastDOOM जानने से पहले मैंने मान लिया था कि खेलते समय Ibuprofen लेना पड़ेगा” में Ibuprofen का क्या मतलब है, समझ नहीं आया

    • शायद कम frame rate से होने वाले headache की बात है
  • अगर लेखक यह देखे, तो पूरे document में John Carmack के surname की spelling “Carnmack” गलत लिखी है

  • अगर cynicism के बिना देखें कि modern software धीमा क्यों है और ऐसी optimizations क्यों नहीं लगतीं, तो इसे standardization/optimization hypothesis से समझाया जा सकता है
    कोई चीज़ standard बन जाती है तो optimization उसके पीछे आती है
    क्योंकि सभी standard tests pass करते हुए सबसे तेज़ होना चाहेंगे
    Doom भी अब ऐसा standard game बन गया है जिसे नए CPU से लेकर toaster तक हर जगह port किया जाता है, और email protocols या browser standards जैसे WebRTC, QUIC आदि भी ऐसे ही हैं
    modern web apps या Electron apps तेज़ इसलिए नहीं हैं क्योंकि वे exploration phase में हैं
    वे हर दिन नई user requirements के हिसाब से update होते हैं, और performance के मामले में इतना तेज़ होना ही काफ़ी है कि बाधा न बने
    इसलिए IRC apps बहुत तेज़ हैं, लेकिन Slack और Teams हमेशा धीमे ही रहने वाले हैं

  • versions में पीछे जाकर improvements और regressions देखना मामूली काम नहीं है
    कुछ optimizations बाद में मिलने वाले bugs बना सकती हैं, और कोई ज़रूरी feature performance गिरा सकता है
    इसलिए हर release से पहले अपने-आप चलने वाले performance tests हों तो ज़िंदगी आसान हो जाती है, और performance problem मिलने पर हमेशा की तरह regression test लिख सकते हैं
    कहना यही है कि performance testing कीजिए