Output a String from a Subroutine

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

Re: Output a String from a Subroutine

Postby Jplus » Sat Mar 10, 2012 12:14 am UTC

We've now officially moved the discussion entirely off-topic, but whatever. :)

I think we (programmers in general) should have more faith in compilers, they do really good jobs at optimizing. Just compare the result of compiling without any optimization-related flags to something with -O3 -DNDEBUG (or /Ox /DNDEBUG). The difference can be overwhelming (not to mention other optimizing flags that sometimes make a difference), even when you've already written very efficient code. Most of the time a compiler will be aware of all optimizations that you can think of as well as many more.

Inlining is a good example. The inline keyword is nowadays mostly ignored by compilers, because the compiler knows much better than the programmer when to do it and when not to do it. If you have some shortish, non-recursive function that you want to slap an "inline" on, you can trust that the compiler will do it even if you don't. And if it doesn't, it's probably for a good reason. Actually, it might do it on some calls but not on others.

Some compilers (or all?) offer a flag so you can let it warn you when it gently denies your inlining request. If it really bothers you. But as the years pass by the inline keyword will probably be forgotten (heck, isn't it even deprecated in C++11?), just like the register keyword.

Now, it's true that RVO doesn't always kick in when you want it. But that's just RVO; it's really not so simple to apply when it depends on runtime information what object should hold the return value. If that bothers you, you can rewrite your function such that it always returns the same object. It might take some swaps, but that's again something your compiler can optimize so it might still improve your code overall.

Forcing the compiler to fail when it cannot apply some particular optimization that you're obsessed with doesn't seem like a good idea to me. I think it will only help to make your code less portable. The compiler is your friend!
Hey, like coding? Perhaps you should check out the red spider project.
Feel free to call me Julian. J+ is just an abbreviation.
User avatar
Jplus
 
Posts: 1098
Joined: Wed Apr 21, 2010 12:29 pm UTC

Re: Output a String from a Subroutine

Postby Goplat » Sat Mar 10, 2012 5:53 pm UTC

Jplus wrote:I think we (programmers in general) should have more faith in compilers, they do really good jobs at optimizing. Just compare the result of compiling without any optimization-related flags to something with -O3 -DNDEBUG (or /Ox /DNDEBUG). The difference can be overwhelming (not to mention other optimizing flags that sometimes make a difference), even when you've already written very efficient code.
Yes, because -O0 generates atrocious code, worse than even a complete novice assembly programmer would write, so of course -O3 will be much faster. That does not mean that -O3 always generates good code. It's very common that it fails to do "obvious" optimizations because of the way the code is written. Probably the most common is redundant memory reads not being optimized due to the compiler not knowing that the location hasn't changed. Another example: despite what most people think, a compiler cannot optimize x/4 into x>>2, because of the possibility that x is negative (/ rounds toward zero, >> rounds toward negative infinity), unless x was declared unsigned.

Inlining is a good example. The inline keyword is nowadays mostly ignored by compilers, because the compiler knows much better than the programmer when to do it and when not to do it.
Not possible. The compiler can know how large the function is, and maybe how many operations can be saved by constant-folding after inlining, but it is ignorant of the single most important factor in deciding whether to inline a function or not: how many times it's called. Inlining functions that are not called very frequently just bloats the program (and makes the whole thing slower due to worse instruction cache usage). This cannot be determined statically, and "profile-guided optimization" is not practical because it's too much work to integrate profiling runs into the build process and those are unlikely to be representative of real-world usage anyway.

Forcing the compiler to fail when it cannot apply some particular optimization that you're obsessed with doesn't seem like a good idea to me. I think it will only help to make your code less portable. The compiler is your friend!
I don't want a computer program to be my "friend". That implies a kind of intellectual parity which cannot exist. Whenever software tries to be "smart", it is at best ineffectual, at worst annoying as hell - because it isn't really smart, it's still just following some set of algorithmic rules, so "smart" really just means "too complex for the user to understand". I like the programs I use to be tools, with predictable behavior. I don't want to have to memorize the 50 rules that determine how a struct is returned; I just want to pass it in by reference and know there's no unnecessary copy.
Goplat
 
Posts: 490
Joined: Sun Mar 04, 2007 11:41 pm UTC

Re: Output a String from a Subroutine

Postby Yakk » Sat Mar 10, 2012 8:19 pm UTC

First, compilers do not ignore the inline keyword. The inline keyword has little to do with inclining by the standard, but any compiler that ignores what it means by the standard would be horribly broken. (In short, it means to ignore linker conflicts on the function's symbol table entry, and not much else - and yes there are a few more nuances, like what is its address).

I would not say "you must RVO this field" but rather have ways to specify language constructs that line up with common optimizations in such a way that the use of the language feature basically guarntees that it is easy to do the optimization. For all of its faults, inline is an example of such a language feature. It does not mean "this function must be unlined" but rather "this function is written in a way that makes it easy to inline" - namely it allows it to be put in a header file.

The fact that it does not check for different implementations sucks. The fact that there is no "inline from another translation unit" keyword also sucks. But both are understandable.

An example of a language feature that would make Nrvo easy would be a function markup that includes the ability for a function call to he part of the construction of an object, together with in function access to a special named return value whose value replaces the use of a valued return.

The first exists, the second some compilers magically detect if all the stars align. Remember, it isn't just multiple different objects that cause the NRVO to fail, but in some cases multiple return statements returning the same value.

You end up having to read the compiler's mind to figure out what quirks it has. And I have nothing against such automatic optimization attempts - but I would also want to he able to hit my compiler over the head with a method that basically every compiler is going to be able to.easily optimize, like how inline is so easy to optimize that people think the keyword MEANS the optimization.
One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision - BR

Last edited by JHVH on Fri Oct 23, 4004 BCE 6:17 pm, edited 6 times in total.
User avatar
Yakk
 
Posts: 10064
Joined: Sat Jan 27, 2007 7:27 pm UTC
Location: E pur si muove

Re: Output a String from a Subroutine

Postby korona » Sun Mar 11, 2012 8:17 pm UTC

Goplat wrote:Probably the most common is redundant memory reads not being optimized due to the compiler not knowing that the location hasn't changed. Another example: despite what most people think, a compiler cannot optimize x/4 into x>>2, because of the possibility that x is negative (/ rounds toward zero, >> rounds toward negative infinity), unless x was declared unsigned.

There is some truth in this statement but not declaring variables as unsigned is clearly the programmer's fault. Fail-when-certain-optimizations-are-not-possible keywords would be nice to have though.

The compiler will know how large the function is, and maybe how many operations will be saved by constant-folding after inlining, but it is ignorant of the single most important factor in deciding whether to inline a function or not: how many times it's called.
Inlining functions that are not called very frequently just bloats the program (and makes the whole thing slower due to worse instruction cache usage). This cannot be determined statically, and "profile-guided optimization" is not practical because it's too much work to integrate profiling runs into the build process and those are probable to be representative of real-world usage anyway.

g++ -profile-generate / -profile-use works pretty good. Usually the size heuristics work well and using the profile does not really improve the performance.

gcc 4.5 has link-time optimizations that can inline functions across translation units.

When you're optimizing a function that is called very often you often have to look at the assembly code in order to make sure that the generated code is optimal.
korona
 
Posts: 118
Joined: Sun Jul 04, 2010 8:40 pm UTC

Re: Output a String from a Subroutine

Postby jocvtrhythgd » Wed Apr 25, 2012 4:11 am UTC

you don't want to allocate memory,
jocvtrhythgd
 
Posts: 5
Joined: Wed Apr 25, 2012 2:01 am UTC

Previous

Return to Coding

Who is online

Users browsing this forum: No registered users and 12 guests