building assembly programs for our advantage.

Started by
7 comments, last by Nickels 20 years, 6 months ago
i know assembly can be used for low-level graphics for speed. and i know it can be used for vertex/pixel shaders. would assembly prove useful in games or general programming otherwise? and if i wanted to write assembly embedded inside c++ using the _asm brackets, where can i find a tutorial or a book that would get a beginner started? and one more thing...is there a difference between using vc++''s _asm and using a separate builder such as TASM or MASM or the various other compilers/builders out there??? I''m just overwhelmed at the many assembler binaries out there and dont want to settle for any random one in fear of using a weak or mediocre or non-standard one. can someone answer these questions and/or lead me to THE standard assembler that i can''t go wrong with for general and games programmers would use? much thanks.
Climb a mountain, every dawn.
Advertisement
quote:Original post by Nickels
i know assembly can be used for low-level graphics for speed.

Well..... maybe. Only if the C++ compiler isn''t optimizing well enough, which it usually does. The only time assembly will give you an advantage over C/C++ (interrupt vectors and such aside) is when you can make an optimization the compiler can''t.
quote:and i know it can be used for vertex/pixel shaders.

Close, but no cigar. The "assembly language" used by vertex and pixel shaders is different from general assembly language.
quote:would assembly prove useful in games or general programming otherwise?

Well, maybe. But there are a few things which make me hesitant of recommending people to use assembly for anything, including game programming:

* It''s usually not necessary. The only optimizations you can do are "micro-optimizations", which don''t affect the high-level structure of the program. Usually, one can get much, MUCH bigger improvements in speed by concentrating on making their algorithms and program flow more efficient. Programmers who concentrate on micro-optimization are losing out on this.

* Unless you''re really really good at it, there''s no reason to. C/C++ compilers, you see, ARE really really good at it, so unless you know a LOT about the architecture you are writing for, your code will be less efficient.

* Assembly code is a lot uglier and harder to maintain than well-written C/C++ code. This is very important when you want to return to your code x number of months/years down the line and make a change.

* A function written in assembly may be less efficient than its C/C++ equivalent if the compiler could have inlined it and done peephole optimizations.
quote:and if i wanted to write assembly embedded inside c++ using the _asm brackets, where can i find a tutorial or a book that would get a beginner started?

All my favorite assembly books are way out of date ... check the "Books and Software" section of this site?
quote:and one more thing...is there a difference between using vc++''s _asm and using a separate builder such as TASM or MASM or the various other compilers/builders out there???

Sort of. _asm is slightly more limited, in ways you probably won''t care about. It''s useful for intermixing assembler and C/C++ in a single function. Separate assembly files, which are compiled by TASM or MASM, are more useful if you have a lot of large, completely assembly functions. Most people are better off with _asm.
quote:I''m just overwhelmed at the many assembler binaries out there and dont want to settle for any random one in fear of using a weak or mediocre or non-standard one.

That''s the least of your concerns. An assembler is an assembler is an assembler. They''re all pretty single-minded in what they do, which is to generate machine code. There''s no concern about things like whether they will optimize for you or recognize logic errors; they won''t.


How appropriate. You fight like a cow.
Here''s a good rule for using assembly in a game.

Take the speed gain (in percentage) that you think you will get from using assembly. Now divide it by 100. This is your actual speed gain.

Of course this rule doesn''t always apply. It is more likely that your code will be slower than the C.

Assembly is good to know, but using it will be a waste of your time unless you know where to optimize, and that means profiling.
In order to make assembly code that is actually faster that the one the compiler generates you have to be a real expert. However, you should still attempt to learn a bit of assembly, as it makes you better when designing data structures and algorithms in a higher level language. Once you know how the CPU really works you can write C++ code more efficient than if you didn''t.
Learn assembly (or rather, how the CPU processes it, lookup how pipelines work, what and why there is cache, scheduling, etc). Then write in C/C++/Object Pascal/Misc x86 native compiler using no assembly, but knowing how your code will be processed by the CPU.

Oh, and never ask "which instruction is faster, A or B". You can and should always profile to find this out, as a "fast" instruction quickly becomes a slow instruction when used in specific situations.
Never try to beat your compiler. It is often better than you so you''ll waste your precious time. Few FPS won''t matter if your game sucks.

ONly thing I can think where assembler would rock is the C++ loops and recursion. Loops are one of the downfalls of this language. They are slow compared to O''Caml for example.
I think there are some repeating assembly instructions that can do a real fast string compare or general memory comparision (repz or something like that).

Such comparisions may be faster if you use assembler, but I don''t know enough about compiler optimizations to be sure.

Value of good ideas: 10 cents per dozen.
Implementation of the good ideas: Priceless.
Proxima Rebellion - A 3D action sim with a hint of strategy
Value of good ideas: 10 cents per dozen.Implementation of the good ideas: Priceless.Machines, Anarchy and Destruction - A 3D action sim with a hint of strategy
BS-er is right about string comparisons being very fast. REP and REPZ are actually prefixes, not instructions. They can also be used for fast string transfers. There are also instructions where you can do batch reads from or writes to I/O ports, but you probably won''t need to use these.

Recursive jumps in ASM are faster than loops in either C++ and ASM.

To compute the average of two numbers in C++ you''d actually be using 2 operations (adding and division). In the Intel instruction set, you have the PAVGB and PAVGW instructions. With either of these, you can compute the average of two values in a single instruction. So, you''ll see a speed increase if you use these. There are even similar instructions that can compute the maximum and minimum of two values.

C++ works more with memory than it does with registers. You can code in ASM in such a way that registers are used more frequently than memory addresses for speed increases.

I''ve seen cases were ASM code can speed up code by as much as 66%.
There are two very simple uses for assembly: bragging rights and a worthy challenge. Saying you wrote a game completely in assembly is sure to impress (either by your courage or sheer stupidity ) others a great deal. Furthermore, between C++ and assembly, C++ is definitively, hands down, easiest to manage.

However, certain chipsets have a special architecture to take advantage of, say, conditional branches, better handling of the cache, etc. In those cases, you can optimise some processor-specific sections of your code to gain speed. Most compilers will write code for the OS it's designed for, not the specific chipset you have. Makes for less portable code but you can take special advantage of processor-specific instructions and strenghts.

In a general-case scenario, however, if you're going for portable code the compiler'll do a good enough job that even if you manage to outcode it, you'll rarely see much of a significant speed increase (unless what you're microoptimising is a really compact loop called a few hundred thousand times a second or something to that end, obviously).

Your code'll probably be faster if you know your way around assembly very well and optimise the parts you know the compiler has a hard time with only, as the rest will probably not vary much. Or if you know the chipset you're going to target with your code and make use of the special chipset-specific instructions and take advantage of its strenghts (ie, better branch prediction, for instance).

[edited by - RuneLancer on October 11, 2003 1:15:37 AM]

This topic is closed to new replies.

Advertisement