17 ms·
Original Age of Empires 2 dev talks about its usage of assembly code
- Havoc 3y ago>The use of assembly in the drawing core resulting in a ~10x sprite drawing speed improvement over the C++ Wow that's a chunky improvement over an already fast lang
- necubi 3y agoThis was in 1999. C++ compilers have come a long ways since then. While there are still opportunities for hand-written asm to go and order of magnitude faster than C++, they're mostly around manual vectorization where the auto-vectorizer fails.
- deleted 3y ago[deleted]
- mysteria 3y agoAnd when that happens SIMD intrinsics are often used rather than going straight into raw assembly.
- pjmlp 3y agoYes, younger devs grown up on the myth of C and C++ being always fast, have missed the days when inline Assembly was a higher count than pure C and C++ code. I have seen applications for MS-DOS, effectively using C as a Macro Assembler, only the data structures and high level logic was C as if Macro Assembler macros.
- loup-vaillant 3y ago> Yes, younger devs grown up on the myth of C and C++ being always fast, have missed the days when inline Assembly was a higher count than pure C and C++ code. And still is in VLC. (Okay, maybe not higher, but they do use a crapton of assembly in their decoders, and it does speed them up by a factor of 10 or so today.)
- pjmlp 3y agoVideo decoding has always been a prime example for SIMD stuff, however I wonder how much of that code VLC devs could wipeout, assuming hardware vídeo decoding being available everywhere.
- hnthrowaway0328 3y agoDo you mean the VLC media player? Just curious is there any reason modern compilers don't beat assemblies or is that simply a legacy issue?
- pjmlp 3y agoCompilers beat hand written Assembly for the general use cases. Now beating special use cases, like using vector instructions to parallel process video decoding streams is another matter. It is no accident that after all the efforts improving Java and .NET JITs for auto-vectorization across various vendors, both platforms now expose SIMD intrinsics as well.
- hnthrowaway0328 3y agoThanks for the explanation. Aside from vectorization is there anything else that handwritten assembly could be better? Assuming on modern CPUs and modern compilers.
- saagarjha 3y agoSure, people who are good at assembly can often do register allocation and instruction selection better for small snippets of code. Or optimize based on guarantees the compiler can’t see or know about.
- neonsunset 3y agoThe choices and resulting codegen are fairly different. Only one of them works "properly" as of today. Though I'm open to be proven wrong once Panama vectors get stable in the Java land.
- Keyframe 3y agoI was there, 3000 years ago, when C was considered bloated and slow. Times are a changing.
- pjmlp 3y agoUnfortunately much of those optimizations are thanks to taking UB to full throttle.
- ack_complete 3y agoEven intrinsics didn't even necessarily work well. MSVC, in particular, was really, really bad back then with SIMD intrinsics -- any use of MMX or SSE intrinsics in VC6 would result in more than two-thirds of the generated code being move instructions, with a single value sometimes moved two or three times between ALU instructions. It was trivial to beat the compiler with hand-written assembly. MMX intrinsics were never fixed and SSE intrinsics weren't fixed until VS2010. For scalar code, it was more that the CPUs got better, as out-of-order execution starting with the Pentium Pro made instruction scheduling less important. The original Pentium CPU was an in-order design with two pipes where the second V pipe had significant restrictions, which was harder for compilers to deal with than the PPro/PII and its decoding pattern.
- jb1991 3y agoAssembly is still used in whole program coding to this day, for example some modern music synthesizers are written in assembly code.
- frozenport 3y agoFunctionality should have been provided by directx though
- iforgotpassword 3y agoI think AOE was using DirectX, so I assume that was one level up the stack, ie figuring out which sprites are visible to which extent by walking different data structures and then just throwing stuff at directdraw.
- Sesse__ 3y agoDirectDraw wasn't really meant as a drawing toolkit; you _did_ have blits, but they were not hardware accelerated AFAIK and not nearly flexible enough for what the article suggests (mirror, stiple, probably other stuff). In general, what DirectDraw gave you was a rectangle you could draw pixels into, and a way to get those pixels efficiently to the screen. In other words, more like a clean abstraction over the display driver.
- ack_complete 3y agoDirectDraw did accelerate blits, but only simple cases, and even then only if the hardware and drivers supported it. Hazy memory is that accelerated blit support was sketchy for pre-3D GPUs, especially stretchblts. It also had significant overhead for drawing small sprites. DirectDraw was critical for video players at the time due to being much faster than GDI and even sometimes Direct3D.
- Sesse__ 3y agoYeah, sounds about right. And yes, obviously it was much faster than GDI for games, since you had more or less direct access to a framebuffer. Not building up some device-independent bitmap and going through some slow path to convert it into the right format for the GPU (which wasn't called a GPU back then, of course).
- rasz 3y ago
- santoshalper 3y agoI love that Michael Abrash shows up in this story. Seems like anywhere graphical innovation happened, he was there.
- cto_of_antifa 3y ago[dead]
- malkia 3y agoI worked on port of a Konami game from PSX to PC, that was 1999-2000 - the code (C) had lots of #ifdefs like where inline assembly was placed, and the original "C" code was kept. It seemed all done by one specific programmer, and what really saved us (in porting) the game was the originallly kept "C" code. My mips knowledge was never as good as x86. So yes, it was the norm back then. My second job (1998), was working on a team that was going to do some software for Intel for the upcoming back then Katmai processor (Pentium I was it). It had all the new fancy SIMD instructions. The software was supposed to be something like media composer - you slap images, rotate them, etc all in realtime using software rendering (GPUs were still relatively expensive). I wrote a bilinear and bicubic texture mapper with marching squares for transparent areas. It was all in assembly, and I spent lots of time optimizing it. Back then we used Intel's VTune, and it was super-precise (for the processors back then) - how they are going to pipeline, how much (supposedly) instructions cycles would take, waits, etc. That helped a lot! But the real lesson was, that me and my manager - both claiming to be super good at assembly (after our recent achievements), rewrote the sphere mapping code for a game another team was writting in assembly, but alas our assembly (but no katmai instructions) code was slower than what the compiler did ;) - TBH, if we did proper mipmapping and texture swizzling we would've fared both ways, but hey, demo coders were not always to be found so they had to rely on regular programmers like us! flipcode keeps a lot of good articles, with lots of good assembly for that - https://www.flipcode.com/archives/articles.shtml https://www.flipcode.com/archives/articles.shtml - there were even better materials from earlier years, but can't find them. Turbo/Borland Pascal were so awesome, because they allowed for very easy of inline assembly use (somehow) than C/C++ - though you had to know which registers you can touch or not.
- zeusk 3y agoAre there any good resources on using mipmapping and swizzling effectively?
- malkia 3y agoI was actually trying to find it - there were lots of .txt files published back then - and there was one about texture mapping from 1992... 1994? - and it explained swizzling and why it was efficient with caches.
- puttycat 3y ago> A key speedup technique AoE used was realized during discussions I had with iD software programmer and optimization guru Michael Abrash over lunch at Tia's Mexican Restaurant in Mesquite, TX. How many freeform interactions like this did we lose because of the Internet's illusion of being connected?
- qingcharles 3y agoI was a game dev in the mid-90s. I had plenty of online conversations on Usenet, IRC and email with guys like Abrash and Jez San etc. It was a much smaller community back then and there was no gatekeeping -- everyone's contact info was out there and inbox zero was still achievable.
- ahstilde 3y agoWe've gained many. Chatting in a discord is similar to this.
- sho_hn 3y agoAnd IRC was even better at it.
- subtra3t 3y agoI don't think so. I know everybody loves to say that IRC is better than [insert commercial chat application] but in this particular use case discord is superior to irc imo because of the voice/video chat features and greater convenience.
- jorvi 3y agoIRC’s biggest fault is no history. Everything else is secondary. Yeah, bouncers exist, but it should have been baked into the spec at some point.
- sho_hn 3y agoIt's the structure/topology. Discord has a million deserted "servers" with redundant general channels. Peak IRC had a dozen or so large networks that often bundled a lot of e.g. adjacent FOSS projects. The chances of running into someone interesting a la the article anecdote was just higher. Discord is a massive net negative for chatting on the internet because of this flaw imho.
- hoten 3y agoYou probably need to ignore the first comment thread to see the comment of interest.
- ThePowerOfFuet 3y agoNot any more; in any case, here's a link to the comment in question: https://old.reddit.com/r/aoe2/comments/18ysttu/_/kgltqrg/ https://old.reddit.com/r/aoe2/comments/18ysttu/_/kgltqrg/
- hnthrowaway0328 3y agoI'm reading a history of Borland and the author claims that the Turbo Pascal compiler was mostly written in assembly and was also used in Delphi 1.0. No one in Borland could make significant changes in the code so eventually they rewrote it for Delphi 2.0. Not sure if all was true but very fascinating. I think there is a certain character in programmers who went through the fire and storm by writing softwares in assembly language for non trivial CPUs (like Pentium and up) that is unique.
- red_admiral 3y agoThose were also the days when, according to a famous interview with the same devs: > The general argument is that if you know you are going to need to release a patch, then you shouldn't be shipping the game in the first place.
- qingcharles 3y agoAs a game dev in the mid-90s patches had just started to appear; you usually got them from a cover disk as most still did not have Internet access. The thought that a title I published might need to be patched after release was something that horrified me.
- HeckFeck 3y agoThis quote shall be summoned every time I open Steam and note there is yet another 22GB 'rebalancing patch' for a certain game.
- alpaca128 3y agoWell, in certain online games the balancing can't just stay static. But update sizes really are quite insane. One Baldur's Gate 3 update had 100GB and of course that required 100GB additional free space. At that point it was easier to just reinstall the whole game.
- red_admiral 3y agoThe balancing in AoE2:DE can't stay static either - and the pathing seems to have a different bug every other patch. Still a fun game though.
- noqc 3y agoThe difference in quality of the game designers who worked on the original AoE2 versus AoE2:DE is pretty apparent. I think what is most annoying to me is how much harder it is to parse the visual information of "what kind of unit am I fighting" now that the graphics are "better".
- anon74747 3y agoAoE2DE still ships with hand-written assembly, though not part of the game code itself. The executable is initially encrypted by an executable packer. It unpacks the game code at runtime - some functions even on-demand. Not sure why they do this, but this even leaves all code as RWX (readable, writable and executable) which is highly insecure.
- plucas 3y agoFor those interested, the competitive AoE2 scene is alive and well with one of its biggest tournaments, NAC5, going on now, an in-person LAN in Berlin. https://liquipedia.net/ageofempires/Nili%27s_Apartment_Cup/5 https://liquipedia.net/ageofempires/Nili%27s_Apartment_Cup/5 https://www.twitch.tv/nili_aoe https://www.twitch.tv/nili_aoe https://www.youtube.com/channel/UCXeY7zz-1LsyZdnpFbffdqA https://www.youtube.com/channel/UCXeY7zz-1LsyZdnpFbffdqA
- dwroberts 3y agoA few years ago I wrote a naive SLP drawing routine and it was very slow, and left me wondering what exactly they did to make it usable in AOE2. So this makes a lot of sense to me. Fun little format to mess with if you find the docs for it - surprisingly not that difficult to implement (there used to be a wiki with the spec on it, might be gone now?)
- Ericson2314 3y agohttps://old.reddit.com/r/aoe2/comments/18ysttu/aoe_is_written_in_assembly_is_this_actually_true_o/kgrh6g6/ https://old.reddit.com/r/aoe2/comments/18ysttu/aoe_is_writte... OOO maybe this is my chance to figure out why the newest "definitive addition" runs so much worse in Wine.
- pranavgoyal 3y agoAoE nostalgia hitting hard!
- qingcharles 3y agoI wrote a good chunk of the graphics code for this commercial isometric game in like 1996: https://www.youtube.com/watch?v=t2kdKB18c7I&t=332s https://www.youtube.com/watch?v=t2kdKB18c7I&t=332s We were just coming out of the age of assembler. The background blitting is all assembler, but the characters are Direct3D. When I put the 3D engine in there it was a 3D software renderer I had written when I was 13 in C++ and x86 and I just pasted it into the game engine, but I think we took the software renderer out and just used Direct3D's renderer. GPUs were just coming onto the market, and I think the hope was that it would get a boost from a GPU, although I don't remember ever testing it on one. (I do remember going to gaming expos and the card manufacturers would just hand out GPUs to every dev that went to their booths...) AMA.