Optimising compilers "efficient"?

All off topic discussions go here. Everything from the funny thing your cat did to your favorite tv shows. Non-programming computer questions are ok too.
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Optimising compilers "efficient"?

Post by Casm »

Anybody who thinks optimising compilers produce wonderfully efficient code should take a look at this master piece. It was produced by the Visual C compiler:

Code: Select all

video_attribute    proc

mov	byte ptr [rsp+8], cl
movzx	eax, byte ptr [rsp + 8]
mov	byte ptr vattrib, al
ret	0

video_attribute    endp

Naturally, if I was writing inefficient assembly code by hand, it might look something like:

Code: Select all

video_attribute    proc

mov byte ptr vattrib, cl
ret

video_attribute    endp
Which is exactly what the original C code does say.
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Optimising compilers "efficient"?

Post by Casm »

berkus wrote:What optimization level?
/Ot
mitikoro
Posts: 11
Joined: Tue Sep 01, 2009 10:19 am

Re: Optimising compilers "efficient"?

Post by mitikoro »

You don't use C because it's fast; you use C because it's maintainable, flexible and portable. Besides, when you are coding an OS you want to create good code, and then fast code (in that order).
When C isn't fast enough, assembly has its place.
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Optimising compilers "efficient"?

Post by Casm »

mitikoro wrote:You don't use C because it's fast; you use C because it's maintainable, flexible and portable. Besides, when you are coding an OS you want to create good code, and then fast code (in that order).
When C isn't fast enough, assembly has its place.
I wouldn't describe that as either good or fast. Another thing: We hear that modern compilers pass arguments in registers, rather than on the stack, because it is "faster". And what is the very first thing they seem to do after a function has been called? Store the parameters on the stack - after first making room for them. Presumably the old "slow" method would have been faster.
mitikoro
Posts: 11
Joined: Tue Sep 01, 2009 10:19 am

Re: Optimising compilers "efficient"?

Post by mitikoro »

I wouldn't describe that as either good or fast.
I agree. But I am talking about the source code, not about the generated code. Good structure design and fast algorithms make programs fast. IMHO it's easier to design portable and efficient structures in C.
(I think) that code works fine, but if it is a big bottleneck, you can always rewrite it in assembler. And I think the term "optimising compiler" is just marketing :) Besides, everybody here profiles his code to find bottlenecks and doesn't trust the compiler.
shikhin
Member
Member
Posts: 274
Joined: Sat Oct 09, 2010 3:35 am
Libera.chat IRC: shikhin
Contact:

Re: Optimising compilers "efficient"?

Post by shikhin »

Hi,

I'm not sure if I understood the assembly dump correctly, but to me it looks like it is a procedure, video_attribute, which writes a value at vattrib.

If I do the same in gcc, with optimization level 2, it inlines the function, and handles it all in one single assembly instruction. So, I suggest you replace your compiler, or play around with the optimization flags a bit (not sure what whatever flag you chose does).

Regards,
Shikhin
http://shikhin.in/

Current status: Gandr.
davidv1992
Member
Member
Posts: 223
Joined: Thu Jul 05, 2007 8:58 am

Re: Optimising compilers "efficient"?

Post by davidv1992 »

/Ot is only one of a number of options that VC takes for optimizing, and it on it's own seems a little pointless. Furthermore, since you didn't provide context about the function you tried to compile there is really no way of knowing why the compiler would do that. It looks to me like there is some room for improvements in it's register allocater, but it could all just be a weird playing together of factors.
Besides, Microsoft hasn't the best reputation for software performance, so judging all compilers by looking just at theirs may be flawed.

Compiling the following (not particularly efficient) implementation of a function to compute greatest common divisor:

Code: Select all

int gcd(int a, int b)
{
	if (a == 0)
		return b;
	else
		return gcd(b%a, a);
}
Gcc given the -O2 flag produces the following code:

Code: Select all

	.file	"test.c"
	.text
	.p2align 4,,15
.globl gcd
	.type	gcd, @function
gcd:
.LFB0:
	.cfi_startproc
	testl	%edi, %edi
	movl	%esi, %eax
	jne	.L5
	jmp	.L8
	.p2align 4,,10
	.p2align 3
.L4:
	movl	%edi, %eax
	movl	%edx, %edi
.L5:
	movl	%eax, %edx
	sarl	$31, %edx
	idivl	%edi
	testl	%edx, %edx
	jne	.L4
	movl	%edi, %eax
	ret
.L8:
	rep
	ret
	.cfi_endproc
.LFE0:
	.size	gcd, .-gcd
	.ident	"GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
	.section	.note.GNU-stack,"",@progbits
Going over this we immediatly see that it has optimized out all stack access except for the mandatory ret. Giving it a closer look also makes it obvious that it optimized out the tail call into a loop, which is also good for performance, all in all it didn't do that bad, and I for one know that it would take me an awful lot of time to really improve on this.

In almost every practical situation I would choose C/C++ over assembly, you might not be able to reach the same level of efficiency in C as you would in Assembly, but it takes a considerable ammount of skill and time to outperform, and most of us won't have neither the skill nor time required to do it.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Re: Optimising compilers "efficient"?

Post by JAAman »

well... first of all, i would have to ask, why you are using invalid switches... that might have something to do with it

... according to MSDN, /Ot is useless without also specifying /Og... which is depreciated -- instead you should be using /O2


WOW... 2 people beat me to the post


edit:
unfortunately, like the previous poster said, we know nothing of the C code used to produce this, nor of the calling code, which would make reasoning hard to do, further, since i am using VCexpress, i cannot test 64bit code generation, so i really cant tell what it would do with valid optimizing switches
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Optimising compilers "efficient"?

Post by bluemoon »

Casm wrote:It was produced by the Visual C compiler:

Code: Select all

video_attribute    proc
mov	byte ptr [rsp+8], cl
movzx	eax, byte ptr [rsp + 8]
mov	byte ptr vattrib, al
ret	0
video_attribute    endp

Naturally, if I was writing inefficient assembly code by hand, it might look something like:

Code: Select all

video_attribute    proc
mov byte ptr vattrib, cl
ret
video_attribute    endp

So, how often you need the video attribute? If it's so often that it need optimized, vattrib should be a dword but the compiler just cannot change that since you told it to use a byte.

And by the way, nice to save a few trillion-th seconds by scarifying code maintainability.
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Optimising compilers "efficient"?

Post by Casm »

JAAman wrote:well... first of all, i would have to ask, why you are using invalid switches... that might have something to do with it

... according to MSDN, /Ot is useless without also specifying /Og... which is depreciated -- instead you should be using /O2


WOW... 2 people beat me to the post


edit:
unfortunately, like the previous poster said, we know nothing of the C code used to produce this, nor of the calling code, which would make reasoning hard to do, further, since i am using VCexpress, i cannot test 64bit code generation, so i really cant tell what it would do with valid optimizing switches

The code could hardly be simpler. It provides limited access to a variable which is otherwise only visible within the file:

Code: Select all

void video_attribute(unsigned char attrib)
{
	vattrib = attrib;
	return;
}
I tried using /O2, but then it started trying to access a static variable through the stack, so I gave up and rewrote part of it in assembly language. It took about ten minutes.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: Optimising compilers "efficient"?

Post by qw »

I don't see the point. Why not make "vattrib" public? What variable may be set but not read?
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Optimising compilers "efficient"?

Post by Casm »

Hobbes wrote:I don't see the point. Why not make "vattrib" public? What variable may be set but not read?
An operating system is a large program. To use a geographicl analogy, if something goes wrong in London, it is preferable to be able to assume that the miscreant is to be found in London, or at most Britain, rather than having somebody up to no good remotely, and possibly situated in any part of the world.

Variables should be available to different parts of the operating system on a need to know basis, and in this case that means procedures involved in text output to the screen, and all living within a single file.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Optimising compilers "efficient"?

Post by gerryg400 »

Code: Select all

video_attribute    proc

mov   byte ptr [rsp+8], cl
movzx   eax, byte ptr [rsp + 8]
mov   byte ptr vattrib, al
ret   0

video_attribute    endp
I don't do much assembly but isn't

Code: Select all

mov   byte ptr [rsp+8], cl
overwriting something in the calling function's stack frame ?
If a trainstation is where trains stop, what is a workstation ?
Casm
Member
Member
Posts: 221
Joined: Sun Oct 17, 2010 2:21 pm
Location: United Kingdom

Re: Optimising compilers "efficient"?

Post by Casm »

gerryg400 wrote:

Code: Select all

video_attribute    proc

mov   byte ptr [rsp+8], cl
movzx   eax, byte ptr [rsp + 8]
mov   byte ptr vattrib, al
ret   0

video_attribute    endp
I don't do much assembly but isn't

Code: Select all

mov   byte ptr [rsp+8], cl
overwriting something in the calling function's stack frame ?
I hadn't thought of that, but at first glance it does look that way. There is no sign of it making room on the stack for anything.

I spent this evening rewriting that entire file in assembler, and guess what - it works now.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Optimising compilers "efficient"?

Post by Solar »

If your code doesn't work, it's the fault of your code, not the fault of the language or your toolchain. (Freak chances in the 0.01-per-mille range nonwithstanding.)
Every good solution is obvious once you've found it.
Post Reply