| Zitat: | ||||||||||||||||||
|
Foreword: this topic is heavily biased, but with a reason, if you're weak-hearted then don't even consider reading this. If you think you should flame me or cause problems, then enjoy your warning. Greetings, Today and probably in the future I'll be posting some topics about the low-level world vs. the high-level world. Basically, I'll also start the first topic in the Programming Discussion board, but I'll also be starting the first topic of the series and I'll probably continue it as well. Basically I've been using nothing else but Assembly for the last two months, basically for the x86(-64) architecture. I'm incredibly fluent in Assembly and if you don't believe me, ask Admiral Refuge. However, Assembly is not the only language I know and use, I also generally use C, C++, Java, BASIC and various other languages and I know how to read, interpret and even port most languages. Anyway, enough about me, lets start with the actual topic. What am I going to cover in this article? Virtually, I'll be covering various languages, especially x86(-64) Assembly, C and C++ and I'll be discussing their performance, but also their standards. Some of us know that Assembly is the lowest-level of programming on the x86(-64) architecture next to actual machine code, which is basically the same, but in a binary form, which the processor can actually interpret and execute. C and C++ are also programming languages, but they're more high-level and thus more abstract than Assembly. Languages like C and C++ are more structural and contain more logical constructions than pure Assembly does. Also, they allow more abstraction than Assembly, especially C++, as C++ provides classes, enumerations, etc. and several design patterns come with them as well. However, all these neat features which should ease up your code have a price, and actually they have two prices. For one everybody will agree that C and C++ will never be faster than Assembly. However, it's still possible to write code that is as fast as Assembly and then again, it isn't. I'll be showing this to you later on, I have some other things to mention first. The second price is that your code won't be easier at all. Think of it, what would be easier? Writing a simple shell script like MS-DOS and UNIX allow, or writing a shell script in C-syntax with preprocessing and everything? I think most people already just prefer to use shell scripts instead of makefiles, why would we even use C-syntax shell scripts then? Don't ask me, as I can't really answer that one. I can however answer the actual question: "Why do people prefer C/C++ (or high-level) over Assembly?" The answer is simple; most programmers can't code. Lets clear that up. Why can't programmers code, according to me? It's quite simple. They can probably write stable and good working code, but most programmers fail at writing properly commented code, which is, in my opinion, a must for good code and most programmers who know Assembly fail at writing properly commented code. GRUB is an example of that, or just AT&T Assembly is. Most programmers who use Assembly just write code like this: Quelltext
That's just plainly horrible; it's void of comments and the AT&T is pretty ugly on itself. If you were to write a new language specification with a full programming toolkit for it and everything and if you used that as your promotion sample, then forget it, it won't work. Most C/C++ is beautiful either in most cases, but yet ugly C/C++ code doesn't look as worse as ugly Assembly code, otherwise nobody would be using WinAPI et al. Anyway, enough about coding styles and habits. Lets talk about the standard of C and C++. Technically speaking it's one of the worst standards of all time. That is, the standard libraries provided with C and C++ miss the proper functionality they should have had like proper Unicode support, proper string classes and such things. C and C++ could have had a standard networking library as well, but either it's because of Microsoft or because most C compiler developers weren't interested into it that it doesn't exist. In short (or tl;dr): C/C++'s standard libraries are flawed. Now, if you're one of the guys who thinks that .net is great at replacing C/C++ and the standard libraries, then GTFO. It isn't and it will never be as it is filled with failure at so many levels. If you feel the need for a virtual machine then you're currently best off with Java, especially since it has better standards than both .net and C/C++. The basic reason behind the fact that C/C++ doesn't have proper standards and specifications is due evolution anyway, that and companies like Microsoft who think they're the only people on this world. However, enough with this talk 'n stuff. It's time to actually look at performance issues. I, for myself, can't even understand why C was actually made. I know it was intentionally made for the creation of the UNIX kernel, but then again, it is not such a great language for kernels at all, as it has many performance issues compared to Assembly. In this article I'll cover that using memcpy. Lets actually implement a memcpy function in pure C and then actually port it to Assembly. So lets first start off with some C: Quelltext
Awesome, now lets see how C usually make a call to the memcpy function: Quelltext
In Assembly the code would look like: Quelltext
Now lets port the memcpy function to x86 Assembly: Quelltext
All the mess with the base pointer is actually part of the cdecl ABI. This code might look great, but it's the worst optimised Assembly around, but it's probably the best you could get in just C. If you're lucky a formal compiler would leave out the cdecl-specific stuff as it isn't required in this case. So you'd end up with: Quelltext
We could actually optimise it in Assembly and that's why libc is or should be implemented in Assembly and not in C. The x86(-64) architecture allows the use of string instructions which are incredibly useful for things like data transfer. If you know a bit about Assembly, you might have heard about lods and stos, but those instructions wouldn't be a good idea at all. It's better to use movs for this job. So lets optimise it: Quelltext
This code alone would be incredibly fast already, but there's still some optimisation left to do. The 8-bit transfer should actually be 32-bit, but how are we going to do that when the size is specified in bytes and not in double words (a.k.a. 32-bit integers)? It's quite simple actually. We just convert the amount of bytes to the amount of double words like in the sample below: Quelltext
That would be the most optimised memcpy function available for C, unless you'd be using something like SIMD extensions or something similar. Here's the 64-bit memcpy as well: Quelltext
That's all. There are now two fully optimised memcpy functions, one for the x86 architecture and the other for the x86-64 architecture. However, it would still be slightly slower than Assembly as you could just set the C-register, the destination index, the source index and use rep movsd/movsq. These functions would however be incredibly fast compared to pure C/C++ and that's why (inline) Assembly should be used for some/most things instead of C/C++ or even Java or the .net framework. Regards, Godlord. |
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!