Anyone try compiling things with -O3 ?


froggyman

Still Fresh
Joined
Nov 29, 2009
Messages
61
Has anyone here tried compiling something like Mupen64 plus with the -O3 (or -Os)flag on make to implement all possible speed boosts in the compiler? I know that it wouldn't be as stable, but it could really help give the N64 emulator a considerable (10ish%) speed increase. I know that daedalusx64 compiles with -Os .


Anything else people may have tried?
 
What makes you think that Mupen64plus was compiled with something other than what's in the Makefile (-O3)?


I'd love to see what benchmarks you used to measure a considerable (10%ish) speed increase.
 
Anything else people may have tried?
I'll pretty much guarantee that anything you can possibly think of that may give it more speed has already been considered. There's no magic button that'll give it more speed here, just Ari64 and Exophase talking way over my head about extremely low level efficiency stuff that may get implemented eventually. :p
 
I can say that -O3 can give very decent speed boosts on my desktop system (x86_64 Linux) as compared with no optimisations, given very unoptomised code it can be >40% faster!


It's very likely that these emulators are very optimised already, in the source - 'inline' is your best friend. Of course most have -O3 in the makefiles too :) .


The only reason NOT to use -O3 is when you want to compile very quickly as optimisations are slow to perform. And therefore it'll eat battery life on your Pandora too but not so much you'd notice. I lied, however, the other reason is for embedded programming where a variable can be edited while the program is running, outside the control of the program, i.e. the memory is changed by another microcontroller by DMA. Anything that might require the ability to do that without bugging up should be defined with the 'volatile' keyword so that you can see where in the source such things can occur, if nothing else.


Compiling with -Os is pretty pointless really - -Os is optimise for size in case anyone wants to know. In the Pandora we have access to a crapton (real SI measurement, you know) of storage, except for the NAND. -Os will make things slower for sure - UNLESS the binary becomes small enough to fit into cache. There's a lot of work behind optimisation but you can just go ahead and -O3 that sucker.
 
Compiling with -Os is pretty pointless really - -Os is optimise for size in case anyone wants to know. In the Pandora we have access to a crapton (real SI measurement, you know) of storage, except for the NAND. -Os will make things slower for sure - UNLESS the binary becomes small enough to fit into cache. There's a lot of work behind optimisation but you can just go ahead and -O3 that sucker.

Apple, for example, uses -Os as a "generally useful" default in their projects. There are tradeoffs (alignment, mainly - no idea if that's a problem on ARM).:

-Os Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further
optimizations designed to reduce code size.


-Os disables the following optimization flags: -falign-functions -falign-jumps -falign-loops -falign-labels


-freorder-blocks -freorder-blocks-and-partition -fprefetch-loop-arrays -ftree-vect-loop-version

I guess for the Pandora you'll use something like -mcpu=cortex-a8 -mtune=cortex-a8 -mfpu=neon too?
 
There are tradeoffs (alignment, mainly - no idea if that's a problem on ARM).

Alignment does make a difference on cortex-a8, however GCC 4.3.3 never aligns code on ARM, even if you specify -O3 and -mcpu=cortex-a8.
 
What makes you think that Mupen64plus was compiled with something other than what's in the Makefile (-O3)?


I'd love to see what benchmarks you used to measure a considerable (10%ish) speed increase.

I don't know why I thought that, just something that came to mind.


I thought that was what I have heard on other emulators, but come to think of it, its probably a totally different case for every emulator and piece of hardware. So I shouldn't really have generalised like I did. Also, I would imagine that if someone would write software that maxes out the OP's hardware they would know what they are doing when it comes to a makefile and optimisations. And that they would know more about those optimisations over someone who has never really had any need to use them on any software he has written.
 
Last edited by a moderator:
Compiling with -Os is pretty pointless really - -Os is optimise for size in case anyone wants to know. In the Pandora we have access to a crapton (real SI measurement, you know) of storage, except for the NAND. -Os will make things slower for sure - UNLESS the binary becomes small enough to fit into cache. There's a lot of work behind optimisation but you can just go ahead and -O3 that sucker.

This reminds me of the old days of Gentoo when people were still under the impression that you can make your system fast by adding crazy optimization flags.


The truth is, more often than not, blindly throwing in -O3 will actually slow down the application. Even if it can't fit into the cache (and Pandora's cache is nowhere near as huge as it is on modern x86_64 porcessors) a smaller binary will produce a lot less cache misses - which is important, because comparing to the processor cache, memory access is slow - CPUs generally waste hundreds of cycles per miss waiting for memory. So before just throwing an -O3 at the application, see first if it actually does perform better than under -O2/-Os. Some do, many don't.
 
This reminds me of the old days of Gentoo when people were still under the impression that you can make your system fast by adding crazy optimization flags.


The truth is, more often than not, blindly throwing in -O3 will actually slow down the application. Even if it can't fit into the cache (and Pandora's cache is nowhere near as huge as it is on modern x86_64 porcessors) a smaller binary will produce a lot less cache misses - which is important, because comparing to the processor cache, memory access is slow - CPUs generally waste hundreds of cycles per miss waiting for memory. So before just throwing an -O3 at the application, see first if it actually does perform better than under -O2/-Os. Some do, many don't.
Yeah that's what I was saying - cache misses are definately bad. I didn't mean the whole program will need to fit into cache, lol.


Hm, some people might take my post out of context, -Os is NOT useless, but what I meant was that you could make the final leap and -O3.


Adding crazy optimisation flags 9/10 WILL make your program faster. Especially if you're not a fan of 'inline'. For any block of code that will run fast loops a lot put it in a new function, declare it 'volatile' and overuse the 'register' keyword.
 
Adding crazy optimisation flags 9/10 WILL make your program faster. Especially if you're not a fan of 'inline'. For any block of code that will run fast loops a lot put it in a new function, declare it 'volatile' and overuse the 'register' keyword.
trollometer.png
 
For any block of code that will run fast loops a lot put it in a new function, declare it 'volatile' and overuse the 'register' keyword.

To expound a little on Alec's remark:


Moving a loop into a function won't make it faster, it'll either make it the same speed (if it ends up being inlined) or slightly slower. How much slower depends on the amount of time it ends up called vs the amount of time it spends looping. There's no possible performance benefit to splitting things into functions if the functions are only called from one place.


You can't declare a function volatile. If you try you'll just end up declaring the type of its return value as volatile instead. If you try doing this on a function returning void you'll probably get a warning. Now, if you meant declare the variables volatile, that won't make your code faster - it'll probably make it slower, since volatile disables all kinds of optimizations on that variable.


The register keyword is close to useless these days on any compiler worth using; back in the day compilers were probably so unsophisticated that they made no attempt to allocate variables to registers unless you explicitly told it to. These days pretty sophisticated algorithms (ie graph coloring) are employed that will allocate variables to registers close to optimally.
 
Moving a loop into a function won't make it faster, it'll either make it the same speed (if it ends up being inlined) or slightly slower. How much slower depends on the amount of time it ends up called vs the amount of time it spends looping. There's no possible performance benefit to splitting things into functions if the functions are only called from one place.
LOL, I think that was sarcasm. If you put things into functions that are only called from one place, then the optimizer can improve it by inlining. (And gcc -O3 will inline all functions that are only called from one place.)


The register and volatile stuff was just silly.
 
If it's called from only one place and is static, anyway. Otherwise it might require link time optimization.
 
If it's called from only one place and is static, anyway. Otherwise it might require link time optimization.
It'll do it even if the function is global. Hopefully the function doesn't get called from any other linked object file, but gcc compiles the function independently just in case it does. This dead code contributes to the code bloat associated with -O3. I'm not sure if the linker has any way of removing it at link time.
 
It'll do it even if the function is global. Hopefully the function doesn't get called from any other linked object file, but gcc compiles the function independently just in case it does. This dead code contributes to the code bloat associated with -O3. I'm not sure if the linker has any way of removing it at link time.

Doesn't here. GCC 4.4.1. I just tried with a function with 45 printfs called from main. Not inlined on -O3 unless I make it static.
 
Doesn't here. GCC 4.4.1. I just tried with a function with 45 printfs called from main. Not inlined on -O3 unless I make it static.
Yes, it seems that it only inlines functions below a certain size, so it does this less than I thought it did.
 
Last edited by a moderator:
Back
Top