Sign in to follow this  
Gink

Speed Question - ASM vs C

Recommended Posts

Quote:
Original post by Daniel Miller
Because it doesn't matter. [smile]


Yeah well im sort of looking for answers from people who arent just saying "Why would you do that" or "it doesnt matter". This is not just about printing to the console, its about everything. How long will it take for compilers to be optimized to the point where they generate the fastest machine code?

Share this post


Link to post
Share on other sites
Quote:
But im just wondering why the compiler isnt optimized to be just as fast as ASM for something like displaying a string.

Displaying strings is not a very important thing to optimze, since it doesn't happen very often (not inner loops). Things like memcpy and bitblt are the places where optimization is really important.

Quote:
its a well known fact that ASM can execute code faster than HLL

This may have been the case somewhere in the past, it is no longer true for modern compilers in most normal cases. Puts still does more then the DOS interupt, things like output redirection, buffering, etc.

Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
The original post makes absolutely no sense at all. The assembly program is a 16 bit real mode snippet to print out a string via interrupts. The C program is a 32 bit protected mode program that makes a function call to a formatted print function that will request the OS to write to a console window. You didn't even tell us what kind of optimizations the C program is compiled with.

In other words, your comparison borders on retarded.


Care to write a 32 bit one and see if it makes a difference?

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
Quote:
Original post by Daniel Miller
Because it doesn't matter. [smile]


Yeah well im sort of looking for answers from people who arent just saying "Why would you do that" or "it doesnt matter". This is not just about printing to the console, its about everything. How long will it take for compilers to be optimized to the point where they generate the fastest machine code?


A while. Or not a while. Depending on your definition of "while". And your definition of "a".

Share this post


Link to post
Share on other sites
The point is not wether C is as fast as ASM... fact on fact... it will _never_ be, it is impossible, considering the extreme amount of optimizations one can do in ASM that is dependent on the current "issue", compilers can't do that, they are general, dealing with each scenario and needs to do work arounds for certain things... just take SIMD, sure you could teach the compiler to use SIMD for certain data types and so on... but still, ASM will always be faster, inevitable.

However, consider 1-5% additional performance and 200-300%+ longer development time.

ASM should be used with care, just as everything else, use ASM where it has major impact, million iteration loops, 3d vectors and so on.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
How long will it take for compilers to be optimized to the point where they generate the fastest machine code?


law of diminishing returns

law of diminishing returns
n.
The tendency for a continuing application of effort or skill toward a particular project or goal to decline in effectiveness after a certain level of result has been achieved.

Noun 1. law of diminishing returns - a law affirming that to continue after a certain level of performance has been reached will result in a decline in effectiveness

Share this post


Link to post
Share on other sites
C compiles into ASM. It's this reason I consider it very silly to say "C is slower than ASM" or anything similar.

Now, what are the differences here?

In the hand written assembly version, you directly make a DOS interrupt in order to achieve your outputting. Printf is a lot more complex, implementing everything, including the kitchen sink. It has to parse a format specifier like "%0.2f" (is that right? It's been ages since I've used printf) check for and accept a variable number of arguments, convert them from numbers/pointers/etc into strings (potentially in base 10, hex, etc), trim them or pad them as desired (with whitespace or other characters), etc etc etc.

This makes comparing the hand written assembly to a call to printf like comparing a toothpick to a nuclear bomb - very very hard to do with any meaningful results :-) (what do they share in common? I guess they're both human made... and... well, human made...)

It's possible to write slow code in any language. If I wanted to, I could make an assembly version of "Hello world" that benchmarked even worse than a C program calculating PI to a million digits, simply by creating a very very long loop. And although such an example is silly, there are plenty of times that when writing in C++ the compiler generates faster assembly than I would have written. I have programs to write, I'm not going to waste an hour to gain a one time 1 millisecond speed boost during a program's initialization, so I'll take the faster to write route. With C++, the optimizer can do this optimization without my intervention, while I still go on to write more code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
Btw, just because C cant go toe to toe with ASM doesnt mean you have to get all defensive.


Since no one has outright told you, you do not have any clue about what you are talking about, and should give up now. The fact that you tried to create a speed comparison using printf and a DOS interrupt would alone be more then enough to show that you don't know anything about benchmarking, let alone language speed comparison.

Yet you don't even seem know much at all about assembly either - I'm guessing you've spent all of a few hours looking at some hello world programs. Interrupt 9, while useful for general purpose output to the command line, is *not* how you would go about outputting strings if blazing speed was your goal (a 16bit C compiler could easily be used to write something that writes and manipulates the text mode video data at segment B800). Also, you didn't mention in your testing methods whether you ran both programs full screen or in a window (it makes a very big difference), not to mention you used a file "Byte2Str.MAC" which you did not provide. I get the feeling the sourcecode you posted is not exactly what you ran to do the benchmark.


Your entire procedure is like taking a Ford and Honda car, running the Ford down a racetrack and timing it, then running the Honda down the track running in reverse the whole way, and drawing a conclusion about speed from that.

Share this post


Link to post
Share on other sites
Quote:
Original post by Michalson
Quote:
Original post by Gink
Btw, just because C cant go toe to toe with ASM doesnt mean you have to get all defensive.


Since no one has outright told you, you do not have any clue about what you are talking about, and should give up now. The fact that you tried to create a speed comparison using printf and a DOS interrupt would alone be more then enough to show that you don't know anything about benchmarking, let alone language speed comparison.

Yet you don't even seem know much at all about assembly either - I'm guessing you've spent all of a few hours looking at some hello world programs. Interrupt 9, while useful for general purpose output to the command line, is *not* how you would go about outputting strings if blazing speed was your goal (a 16bit C compiler could easily be used to write something that writes and manipulates the text mode video data at segment B800). Also, you didn't mention in your testing methods whether you ran both programs full screen or in a window (it makes a very big difference), not to mention you used a file "Byte2Str.MAC" which you did not provide. I get the feeling the sourcecode you posted is not exactly what you ran to do the benchmark.


Your entire procedure is like taking a Ford and Honda car, running the Ford down a racetrack and timing it, then running the Honda down the track running in reverse the whole way, and drawing a conclusion about speed from that.


My comparison is more like comparing a car to a bicycle

Share this post


Link to post
Share on other sites

#include <cstdio>

//access to GetTickCount, Sleep
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

const char* String = "This is a test string that is reasonably long.\n";

unsigned int TestC()
{
unsigned int Start = GetTickCount();

for( unsigned int x = 0; x < 0xffff; ++x )
{
puts( String );
}

unsigned int End = GetTickCount();
return End - Start;
}

unsigned int TestASM()
{
unsigned int Start = GetTickCount();

__asm
{
mov esi, 0xffff
LoopStart:
mov eax, String
push eax
call puts
add esp, 4
sub esi, 1
jne LoopStart
}

unsigned int End = GetTickCount();
return End - Start;
}

int main()
{
unsigned int TimeC = TestC();
printf( "C test done, starting assembly test...\n" );
Sleep( 1000 );
unsigned int TimeASM = TestASM();

printf( "Time for C: %d\nTime for ASM: %d\n", TimeC, TimeASM );

return 0;
}








That's a fair test. Not surprisingly, it comes up pretty much dead even between C and assembly. (By the way, if you happen to know a way of outputting text in protected mode Win32 other than calling puts from assembly...)

Share this post


Link to post
Share on other sites
Quote:
Original post by Daniel Miller
<3 Michalson

edit: If you knew that, why did you post it? T-T

This reminds me of when I used to argue against using libraries in QBasic, because I thought it was cheating. [grin]


Im not using ASM because I think HLL are cheating. They are just at such a high level that you dont know what is going on in your computer. I dont want to be dumbed down by the high level of abstraction that HLL's provide.

Mich - is there something wrong with learning a new language?

How can you compile that with g++ Promit?

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
How can you compile that with g++ Promit?


You can't, GCC won't accept Intel syntax assembly. Feel free to convert it to AT&T syntax, if you dare. And obviously you'll need a different timing function if you're not on windows. gettimeofday() should suffice.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
Mich - is there something wrong with learning a new language?


No, I think it's great to learn a new language, especially something like assembly where you can get a better understanding of how high level languages work (even Carmack admits to this - in a question about why he was using C over C++ at the time, he said it was because it was easier for him to see how his C code was going to get compiled into assembly, and thus he could write more compiler friendly code in C then C++).

What you've done wrong however is after spending the metaphorical 5 minutes learning the basics of assembly, you've decided that you are some sort of master (and not just of assembly, but of benchmarking too), and proceeded to post all the junk in this thread.

Perhaps the first post, out of ignorence, was passable, but everything after that, like the snide remarks about how C couldn't cut it (a statement which is planely false), was frankly retarded. You've made yourself look like a deluded idiot, and wasted everyones time by doing it publicly.

Share this post


Link to post
Share on other sites
Quote:
Original post by Gink
Quote:
Original post by Michalson
Your entire procedure is like taking a Ford and Honda car, running the Ford down a racetrack and timing it, then running the Honda down the track running in reverse the whole way, and drawing a conclusion about speed from that.


My comparison is more like comparing a car to a bicycle


No, it's not. Comparing a car to a bicycle would be comparing a faster thing to a slower thing and getting an accurate benchmark. You have taken two very close things, and tried to benchmark them in a way that does not in any way accurately compare them - the Honda running backwards is not going to produce the same result as the Ford, even if both cars have exactly the same top speed. The method used to compare the two (or rather the genius who came up with it) is at fault, not the Honda.

Share this post


Link to post
Share on other sites
Quote:
Original post by Michalson
Quote:
Original post by Gink
Quote:
Original post by Michalson
Your entire procedure is like taking a Ford and Honda car, running the Ford down a racetrack and timing it, then running the Honda down the track running in reverse the whole way, and drawing a conclusion about speed from that.


My comparison is more like comparing a car to a bicycle


No, it's not. Comparing a car to a bicycle would be comparing a faster thing to a slower thing and getting an accurate benchmark. You have taken two very close things, and tried to benchmark them in a way that does not in any way accurately compare them - the Honda running backwards is not going to produce the same result as the Ford, even if both cars have exactly the same top speed. The method used to compare the two (or rather the genius who came up with it) is at fault, not the Honda.




Even if this was going forward, i dont think it can compete with the ford

Share this post


Link to post
Share on other sites
Gink, you're looking less and less like a misinformed but honest intentioned person and more and more like an idiotic zealot. You've decided (falsely, I might add) that assembly is faster than C and you're determined to stick to that, no matter what.

Share this post


Link to post
Share on other sites
Quote:
Original post by Promit
Gink, you're looking less and less like a misinformed but honest intentioned person and more and more like an idiotic zealot. You've decided (falsely, I might add) that assembly is faster than C and you're determined to stick to that, no matter what.


Im not going to argue with you, randy hyde is though

AOA
Quote:
Original post by Promit
Gink, you're looking less and less like a misinformed but honest intentioned person and more and more like an idiotic zealot. You've decided (falsely, I might add) that assembly is faster than C and you're determined to stick to that, no matter what.


Assembler is faster than C... there is no way that C could be faster than assembler... it is just all about how much faster... and in that manner, I don't regard ASM as a languange, rather as a possibility for optimizations.

You cannot really compare ASM and C if you are going to live in the real world, developing a major project in pure ASM is not going to happen, not ever ever ever.

So really, why care to drag this discussion out? If you want that extra little optimization somewhere, go ASM... otherwise, seriously, you don't use ASM if you want to make that printing to the console 2 instructions faster, you do it if you feel that it could really provice a major improvement to performance or be suitable.

Share this post


Link to post
Share on other sites
Maybe I missed it in the midst of all the rants but the original post didn't say what OS environment this was tested under.

DOS function 9 is little more than a glorified memcpy.

puts() on any vaguely modern OS is a much different beast. puts() has to copy the string to a stream (which may not actually be the screen if stdout has been redirected). This data has to get buffered up and then it may or may not get flushed to the OS immediately. This introduces yet another indirection and buffering layer. On Windows the string then has to get copied over to the console control service to do the actual printing. Eventually it becomes time to actually draw the string. Since this is 2005 and not 1985 you're probably running a GUI which means finding the right font, possibily going through a very expensive rendering process for each character (if you're using a Truetype or similiar console font), building a bitmap to get copied to the screen, and possibly doing composition rather than a simple opaque blt.

Share this post


Link to post
Share on other sites
Okaaaaay... I'm tired and I think we can all agree that this thread has probably out stayed its welcome.

Debates about performance surface fairly regularly on gamedev and very rarely are they based on sound reasoning and good judgement.

I think we can all agree that a good assembly programmer combined with appropriate circumstances can produce code which is "better" (subjective term) than the compiler would have produced given the self same information.

However, my, and I think most peoples' objection to this premise of this thread is that it attempts to argue a case based on a test which compares apples and oranges.

An finally, at the risk of making a cheap point, Art of Assembly hasn't been updated in any great way since, and I quote, 30 SEP 1996. Yes, I agree, not everything has changed, but it still doesn't make the standard DOS interupts in any way comparable to printf.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this