views:

196

answers:

4

Suppose you've written a portable C++ code which runs smoothly on different platforms. To make some modifications to optimize performance, you use inline assembly inside your code. Is it a good practice (compiler optimization set aside) or will it make troubles for portability?

+14  A: 

Obviously it breaks portability - the code will only work on the specific architecture the assembly language is for. Also, it's normally a waste of time - the compiler's optimiser is almost certainly better at writing assembler code than you are.

anon
"the compiler's optimiser is almost certainly better at writing assembler code than you are." - unfortunately just turning on stuff like SIMD can be a task almost as challenging as writing a short bit of assembler code ;-)
Steve Jessop
@Steve All right - almost certainly better than I am, then.
anon
There are few (very few) humans around that are better at assembly than the compiler. Even if there was an optimization it is likely that a new release of the compiler will soon include that optimization and thus just re-compiling your code gives you better code (while assemble must be continuously maintained).
Martin York
For non-SIMD x86, the compiler usually beats a human. For in-order CPUs, a moderately experienced assembly language programmer seems to stand a better than fighting chance...
brone
+5  A: 

Obviously the inline assembly isn't even close to portable. To maintain any portability at all, you generally have to use an #ifdef (or something on that order) to determine when to use it at all.

My own preference is to segregate the assembly language into a separate file, and in the makefile decide whether to build the portable version or the assembly language version.

Jerry Coffin
Also, note that just because this bit of code was the proven bottleneck on one platform, and just because you managed to improve performance on this platform by assembler coding, doesn't mean that either of those things will be true on some other platform. So the original code is still the first attempt on a new platform, until properly profiled.
Steve Jessop
+2  A: 

It depends.

If you have only x86 assembly, your application won't ever run on ARM and native x64. To solve this, you can surround it with #ifdef's depending on the architecture. This is the approach cross-platform, highly optimized libraries such as h264 use. In most cases, though, it's not worth it. Just use very specific C and it will behave very similarly to native assembly.

Clark Gaebel
IMHO, a better solution is to place functions with assembly language into separate assembly language source files. Let the build process choose the correct source files based on the target platform.
Thomas Matthews
+2  A: 

The other obvious choice is to only implement inline assembly on certain architectures, and keep the original (unoptimized) C++ for any other architecture, rather than trying to generate assembly for all architectures. (Suitably #ifdefed, of course.) Then you get the benefit of the optimization on the one architecture, with the basic functionality on all.

However, when we've done this on projects I've worked on in the past, this was the worst part to maintain - some other piece of code would change, and exactly what was being passed into the isolated function(s) would change, and the original C++ and assembly wouldn't match any more, and there was much wailing and gnashing of teeth.

Michael