4 ms·
C is a high level language with capability of low level access: we regularly made fun of C programmers in high school (like my math teacher) because they didn't
by Annatar 7y ago
C is a high level language with capability of low level access: we regularly made fun of C programmers in high school (like my math teacher) because they didn't know how to code in assembler and had to write abstract high level code in C, in order for the compiler to do it for them. The biggest brouhaha was always disassembly of "optimized" machine code generated by the C compiler, full of needless stack twiddling and housekeeping code, wasting hundreds or even thousands of CPU cycles on what amounts to useless abstractions. That's nonsense one finds only in a high level language. But it's always super for a good brouhaha!
- ummonk 7y agoWe've long since moved on from an era when anything above assembly could be considered high level. And the performance difference between idiomatic C code compiled with -O3 (to inline functions and minimize the stack twiddling and housekeeping code) and handwritten straightforward assembly is low enough as to be negligible. Not so with, say, Haskell vs C.
- Annatar 7y agoNeither is true. Well, the first might be true for you in your mind, but doesn't change the fact that C is a high level language modelling an abstract system, and providing that model through its standard libraries (which is what makes it possible to write portable code). And the second with -O3 could not be more wrong, and I can prove it: compile anything with gcc -S -O3 and behold the extra code which a human would never write because it's unnecessary.
- tom_mellior 7y ago> I can prove it: compile anything with gcc -S -O3 and behold the extra code which a human would never write because it's unnecessary. Since you claim that that's true for "anything", care to show us an example consisting of a 5-10 line C function and your assembly version?
- Annatar 7y agoConsidering I wrote above exactly what to do (gcc -S), I believe you are not making this request in good faith; rather, you seek to test whether I know what I'm writing about. However, had you done what I told you to do, you wouldn't have asked. That's why I think you are actually trolling me.
- tom_mellior 7y agoInput code: float dot_product(float *a, float *b, int n) { float result = 0.0f; for (int i = 0; i < n; i++) { result += a[i] * b[i]; } return result; } Output from gcc -O3 -S: .file "foo.c" .text .p2align 4,,15 .globl dot_product .type dot_product, @function dot_product: .LFB0: .cfi_startproc testl %edx, %edx jle .L4 leal -1(%rdx), %eax pxor %xmm0, %xmm0 leaq 4(,%rax,4), %rdx xorl %eax, %eax .p2align 4,,10 .p2align 3 .L3: movss (%rdi,%rax), %xmm1 mulss (%rsi,%rax), %xmm1 addq $4, %rax cmpq %rax, %rdx addss %xmm1, %xmm0 jne .L3 rep ret .p2align 4,,10 .p2align 3 .L4: pxor %xmm0, %xmm0 ret .cfi_endproc .LFE0: .size dot_product, .-dot_product .ident "GCC: 7.4.0" .section .note.GNU-stack,"",@progbits Where's the unnecessary code? What does your hand-optimized version look like? Is your hand-optimized version faster than this?
- Annatar 7y agoThis is how a human would code the same (a human would know, for instance, that (s)he wants to multiply 50 times, passing that in %rax (that would be your "n" in C), something a compiler can never know, which is one of many reasons (and there are many!) why a compiler can never, ever beat a human at coding in assembler: DotProduct: subss %xmm0, %xmm0 .Loop: movss (%rdi, %rax, 4), %xmm1 mulss (%rdi, %rax, 4), %xmm1 addss %xmm1, %xmm0 subq $1, %rax cmpq $0, %rax jnz .Loop ret ...potentially, depending on how 80x86 processors work, the Z flag might be set when subq $1, %rax reaches 0 and the cmpl $0, %rax could be optimized away, making the code even shorter (and faster). But I'll leave it in there because this handily beats the compiler in both size and speed, even with the compiler often trying to cheat with nopw instructions to warm up the data cache. Now compare that with the garbage GCC generated. At -O3 no less! What a bunch of garbage! On a personal note, you forced me to write code for a processor architecture I do not even know (80x86 family of processors in 64-bit mode), at all, so you just assumed my primary system is powered by that intel / AMD garbage of processors, and I don't appreciate that one bit. And you doubted me, which I appreciate even less.