Thursday, April 23, 2015

Digest for comp.lang.c++@googlegroups.com - 25 updates in 4 topics

Thomas Richter <thor@math.tu-berlin.de>: Apr 23 09:05AM +0200

> Assume you have a class template parameterized by some set of types that provides some functionality. In the system there are three specific instantiations of that template. In another codebase a developer has created exactly the c++ code that those templates instantiations (i.e. 3 hand written classes that are verbatim the same except for naming). In this situation are there optimizations that can make the template version faster than the the handwritten?
 
> In a nutshell are there advantages to using templates that can make it even faster than, say generated code with exactly the same content? If there are what are those optimizations?
 
That's one of the questions that are hard to answer without having
access to the compiler and the code in question. But one thing for sure:
Having the code *once* (and templated) makes it surely easier to
maintain and extend than to have it thrice and having to keep three
implementations consistent.
 
Greetings,
Thomas
Melzzzzz <mel@zzzzz.com>: Apr 23 10:17AM +0200

On Wed, 22 Apr 2015 14:39:10 -0700 (PDT)
 
> In a nutshell are there advantages to using templates that can make
> it even faster than, say generated code with exactly the same
> content? If there are what are those optimizations?
 
I would be surprised if performance wouldn't be same.
"Öö Tiib" <ootiib@hot.ee>: Apr 23 05:05AM -0700

On Thursday, 23 April 2015 00:39:22 UTC+3, Daniel Davidson wrote:
> instantiations (i.e. 3 hand written classes that are verbatim the
> same except for naming). In this situation are there optimizations
> that can make the template version faster than the the handwritten?
 
One difference is that the templates are header-only.
The ordinary classes (and also full specializations of templates)
are typically split between interface declaration in header file
and translation unit that implements the functionality.
 
That makes templates to compile slower but gives better
opportunities for the compiler to optimize. Also linkers
sometimes merge code of different instances (that happen to
do exactly same thing) behind same binary code.
 
> In a nutshell are there advantages to using templates that can make
> it even faster than, say generated code with exactly the same
> content? If there are what are those optimizations?
 
The efficiency is actually not that interesting advantage. You pay
with slow compilation and linking and achieve that something that
was sufficiently fast is maybe some % faster. The advantage is lack
of maintenance head-ache of the alternative: massive copy-paste.
 
Lets imagine that there are *only* six copy-pastes of ~500 lines
class and only *one* defect lurking in it.
 
* The defect is reported by testing about "first" and fixed in that.
* It is reported slightly later in "second" and fixed in that too
but differently, by other guy.
* Some change is requested for "sixth" and yet another maintainer does
modify it but the defect is still there.
* The issue is later found in "third" too but experienced maintainer
senses Déjà vu. So he searches for copy-paste and finds "second",
"third", "fourth" and "fifth". The "first" and "sixth" have been
changed enough so search engine did not find those. He fixes the
4 copies he found in third way.
* Same change is requested for others five that was done in "sixth".
 
The two different fixes that are applied now to "second" did break
something else in it and "sixth" is still broken. Other five need
to be changed. Bear in mind that it was oversimplified toy example.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 05:39AM -0700

On Thursday, April 23, 2015 at 2:05:55 AM UTC-5, Thomas Richter wrote:
> implementations consistent.
 
> Greetings,
> Thomas
 
I should not have said hand-written. This question theoretical - but the setting is actually code generation versus templates. Generated code is easier to understand/debug, etc. But I want to find if and when templates can outperform.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 05:44AM -0700

On Thursday, April 23, 2015 at 7:05:41 AM UTC-5, Öö Tiib wrote:
 
> The two different fixes that are applied now to "second" did break
> something else in it and "sixth" is still broken. Other five need
> to be changed. Bear in mind that it was oversimplified toy example.
 
Good points. I wanted to keep the question theoretical - but the real setting is templates vs code generation. We have no problem doing either and even mixing both. I want to know of any real *performance* advantages of templates over code generation. Compile time and headaches of each are understood but the real question is - can a compiler do better with a template in terms of faster code. If so under what circumstances?
"Öö Tiib" <ootiib@hot.ee>: Apr 23 08:51AM -0700

On Thursday, 23 April 2015 15:44:22 UTC+3, Daniel Davidson wrote:
> time and headaches of each are understood but the real question
> is - can a compiler do better with a template in terms of faster
> code. If so under what circumstances?
 
I can try to elaborate. A template *is* technically script for
the code generator that is built into compiler. Compiler "knows"
that the code of template instatiation is generated and it does
not know that about code generated externally.
 
I already wrote about template being header-only. If the other
code generator also generates header-only code then they are on
equal grounds in that sense. Header-only can give serious
advantages but there are several things that are tricky to do
header-only for non-template.

Rest of it is quality of implementation of both contenders.
 
Modern C++ compilers do excellent work optimizing on all levels.
Everybody see how it is difficult for debugger to map the
optimized code back to C++ text again. On other hand it is tricky
to express some meta-knowledge (likely known for code-generator
writer) in current C++. "Reflection" and "Concepts" might
help ... but these are only future plans right now.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 09:15AM -0700

I totally agree. A colleague mentioned a set of optimizations that a compiler can perform when dealing with templates that it could not do of the code were generated. Something along the lines of "because the compiler has special information that ties all template instances of a parameterized class together it can find ways of generating more runtime efficient code that the code generation case. I'm specifically looking for any such example - or an authoritative *no - that is not possible*.
Martin Shobe <martin.shobe@yahoo.com>: Apr 23 11:57AM -0500

On 4/23/2015 11:15 AM, Daniel Davidson wrote:
> I totally agree. A colleague mentioned a set of optimizations that a compiler can perform when dealing with templates that it could not do of the code were generated. Something along the lines of "because the compiler has special information that ties all template instances of a parameterized class together it can find ways of generating more runtime efficient code that the code generation case. I'm specifically looking for any such example - or an authoritative *no - that is not possible*.
 
I'm afraid you won't get either. I can't think of any optimizations that
a compiler can perform on a template that it can't perform on code
generated functions. It might be easier for the compiler to optimize the
template and therefore more likely to actually be optimized, but a
compiler could still perform it in the other case as well.
 
In the end, the answer to the question of whether or not you should
generate templated or non-templated code boils down to.
 
1) Is the performance of the generated code critical? If not, answer
based on the maintainability of the code-generator (not the generated
code as I'm assuming that you won't have to maintain the generated code
directly.).
 
2) Otherwise, do it both ways and measure the results. Do it the more
performant way.
 
Martin Shobe
woodbrian77@gmail.com: Apr 23 11:31AM -0700

On Thursday, April 23, 2015 at 11:15:51 AM UTC-5, Daniel Davidson wrote:
> I totally agree. A colleague mentioned a set of optimizations that a compiler can perform when dealing with templates that it could not do of the code were generated. Something along the lines of "because the compiler has special information that ties all template instances of a parameterized class together it can find ways of generating more runtime efficient code that the code generation case. I'm specifically looking for any such example - or an authoritative *no - that is not possible*.
 
I'm skeptical about what your colleague says. As Iiib said,
a C++ compiler "knows" the source of the generated code in case
of a template instantiation. Is that something it can build on
in order to make optimizations?
 
Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net
woodbrian77@gmail.com: Apr 23 11:56AM -0700

On Thursday, April 23, 2015 at 10:52:17 AM UTC-5, Öö Tiib wrote:
 
> Header-only can give serious
> advantages but there are several things that are tricky to do
> header-only for non-template.
 
What tricky things do you mean?
 
> to express some meta-knowledge (likely known for code-generator
> writer) in current C++. "Reflection" and "Concepts" might
> help ... but these are only future plans right now.
 
Are modules getting lost in the shuffle? I hope not.
 
Brian
Ebenezer Enterprises - "Buy truth, and do not sell it,
get wisdom and instruction and understanding." Proverbs 23:23
 
http://webEbenezer.net
scott@slp53.sl.home (Scott Lurndal): Apr 23 07:03PM

>a C++ compiler "knows" the source of the generated code in case
>of a template instantiation. Is that something it can build on=20
>in order to make optimizations? =20
 
The compiler will translate the template definition into an
internal intermediate representation. This representation
is designed in such a way as to allow optimization before
the code generation phase. It is much easier to apply
transformations to the intermediate representation than it
is to [re]optimize already generated object code.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 01:48PM -0700

On Thursday, April 23, 2015 at 2:03:19 PM UTC-5, Scott Lurndal wrote:
> the code generation phase. It is much easier to apply
> transformations to the intermediate representation than it
> is to [re]optimize already generated object code.
 
This knowledge is what I'm after. Do you have a concrete example of such an optimization that occurs in the one case and not in the other?
 
This is maybe better asked in a c++ compiler group. Anyone know of a better forum to ask this question?
 
In particular I'm interested in a real optimization - not just an ability to. Although knowing something that can be optimized but is not yet supported by compilers would be useful too.
scott@slp53.sl.home (Scott Lurndal): Apr 23 08:56PM


>This knowledge is what I'm after. Do you have a concrete example of such an optimization that occurs in the one case and not in the other?
 
>This is maybe better asked in a c++ compiler group. Anyone know of a better forum to ask this question?
 
>In particular I'm interested in a real optimization - not just an ability to. Although knowing something that can be optimized but is not yet supported by compilers would be useful too.
 
Gcc and LLVM are both open-source. As Linus is wont to say,
'use the source, luke'.
scott@slp53.sl.home (Scott Lurndal): Apr 23 08:57PM


>This knowledge is what I'm after. Do you have a concrete example of such an optimization that occurs in the one case and not in the other?
 
>This is maybe better asked in a c++ compiler group. Anyone know of a better forum to ask this question?
 
>In particular I'm interested in a real optimization - not just an ability to. Although knowing something that can be optimized but is not yet supported by compilers would be useful too.
 
You may also wish to consult the dragon book.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 02:05PM -0700

On Thursday, April 23, 2015 at 3:56:53 PM UTC-5, Scott Lurndal wrote:
 
> >In particular I'm interested in a real optimization - not just an ability to. Although knowing something that can be optimized but is not yet supported by compilers would be useful too.
 
> Gcc and LLVM are both open-source. As Linus is wont to say,
> 'use the source, luke'.
 
my force are not so strong.
Daniel Davidson <phyton.dbd@gmail.com>: Apr 23 02:06PM -0700

On Thursday, April 23, 2015 at 3:57:28 PM UTC-5, Scott Lurndal wrote:
 
> >This is maybe better asked in a c++ compiler group. Anyone know of a better forum to ask this question?
 
> >In particular I'm interested in a real optimization - not just an ability to. Although knowing something that can be optimized but is not yet supported by compilers would be useful too.
 
> You may also wish to consult the dragon book.
 
not looking for theory - just an answer to specific question.
Alain Ketterlin <alain@dpt-info.u-strasbg.fr>: Apr 23 11:58PM +0200

>> is to [re]optimize already generated object code.
 
> This knowledge is what I'm after. Do you have a concrete example of
> such an optimization that occurs in the one case and not in the other?
 
No, because there is none. Templates are a source language ("front-end")
thing. They are pure syntax, and template instanciations can be thought
of as being transformed into various pieces of concrete (i.e., not
template) source code before entering the rest of the compilation
pipeline ("middle-end" for target-independent optimizations, and then
"back-end" for architecture-specific optimizations and code-generation).
This ensures optimizations apply to all languages supported by the
compiler.
 
Of course, the details will vary from one compiler to the other. For
instance, gcc front-ends translate into a format called GIMPLE.
LLVM-based compilers (like clang) translate into, well, LLVM (which is
not a compiler, but rather an intermediate representation---but the name
is also used as an huge number of "optimization passes" and the
orchestration infrastructure). As far as I know, none of these
intermediate representations care about templates. The corresponding
front-ends process templates with their own format (see, e.g., clang's
AST at http://clang.llvm.org/docs/IntroductionToTheClangAST.html).
 
> In particular I'm interested in a real optimization - not just an
> ability to. Although knowing something that can be optimized but is
> not yet supported by compilers would be useful too.
 
Go to llvm.org and check documentation there:
 
- http://llvm.org/docs/LangRef.html describes the intermediate
representation LLVM optimization passes work on
 
- http://llvm.org/docs/Passes.html gives you a list of common passes
 
The docs on gcc internals is at https://gcc.gnu.org/onlinedocs/gccint/
 
There are many things that can be optimized but are not (see
http://en.wikipedia.org/wiki/Full_employment_theorem for an extreme
view on the question). But this does not mean that it is easy to find
something valuable to add...
 
-- Alain.
Doug Mika <dougmmika@gmail.com>: Apr 23 12:34PM -0700

Hi to all, I had a quick question.
 
I have a small simple program (I don't want to reproduce the entire thing as most likely it will be unnecessary) that has a vector<int> with some elements. It uses an iterator to find a particular value, and using the distance function it computes the distance to the located element.
 
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
...
 
vector<int>::iterator iElement = find(vecIntegerArray.begin(), vecIntegerArray.end(), 2991);
 
//Check if the value was found
if(iElement != vecIntegerArray.end())
//Value was found...Determine position in Array
int Position = distance(vecIntegerArray.begin(), iElement);
...
}
My question is, I DID NOT include <iterator> library, what distance() function am I using in this piece of code?
Marcel Mueller <news.5.maazl@spamgourmet.org>: Apr 23 09:53PM +0200

On 23.04.15 21.34, Doug Mika wrote:
> #include <iostream>
> #include <vector>
> #include <algorithm>
[...]
> My question is, I DID NOT include <iterator> library, what distance() function am I using in this piece of code?
 
The standard library headers are allowed to include each other. So the
<iterator> include might be included indirectly by one of the others,
e.g. <algorithm>.
 
Of course, no program should rely on that - in fact many do so.
 
 
Marcel
Barry Schwarz <schwarzb@dqel.com>: Apr 23 02:15PM -0700

On Thu, 23 Apr 2015 12:34:13 -0700 (PDT), Doug Mika
>...
>}
>My question is, I DID NOT include <iterator> library, what distance() function am I using in this piece of code?
 
You do not include libraries. You include headers.
 
Headers are used by the compiler. They contain the declarations for
the functions you wish to use so the compiler knows how to generate
the code to invoke those functions. (Consider the possible need to
convert an argument from int to double as in pow(2,3) or the ability
to specify default values for omitted arguments.) If you call a
function for which there is no declaration in scope, you should
receive a diagnostic.
 
Libraries are used by the linker. When you code a call to a function,
the compiler generates an entry in the object module that references
that function. The linker will then try to find the definition of
that function in one of the libraries it knows to look through.
 
There is no inherent relationship between a header and a library. It
is possible for the functions declared in a single header to be spread
out across several libraries. It is just as possible for the
functions declared in several headers to be collected into a single
library.
 
To answer your question, if the reference to distance was resolved by
the linker, you are using the same distance function whether you
include the <iterator> header or not. If it was not resolved, the
linker should have issued a diagnostic and you would need to inform
the linker where it should look for the function.
 
--
Remove del for email
Ian Collins <ian-news@hotmail.com>: Apr 23 01:50PM +1200

David Brown wrote:
> void g() override;
> };
 
> Then it doesn't look too bad.
 
It's kinder on the eye, but may case problems if someone has used
override for a variable name! Don't forget that as a contextual
keyword, you can still use override as an identifier.
 
--
Ian Collins
David Brown <david.brown@hesbynett.no>: Apr 23 09:17AM +0200

On 23/04/15 03:50, Ian Collins wrote:
 
> It's kinder on the eye, but may case problems if someone has used
> override for a variable name! Don't forget that as a contextual
> keyword, you can still use override as an identifier.
 
The people writing parsers for C++ must /love/ these contextual keywords!
 
Yes, it would conflict with using override as an identifier. But I
think you'd get a fairly obvious error message if you did so, and change
the code appropriately when moving to C++11 (just because you /can/ use
"override" as an identifier as well as a contextual keyword, does not
make it a good idea).
"Öö Tiib" <ootiib@hot.ee>: Apr 23 01:41AM -0700

On Thursday, 23 April 2015 10:17:28 UTC+3, David Brown wrote:
> > override for a variable name! Don't forget that as a contextual
> > keyword, you can still use override as an identifier.
 
> The people writing parsers for C++ must /love/ these contextual keywords!
 
That ship has sailed long ago. Count of of little code snippets
to detect how close a parser is to give good impression of parsing
old C++ in a conforming manner is millions.
http://www.ace.nl/sites/default/files/SuperTest.RR_.pdf
 
> the code appropriately when moving to C++11 (just because you /can/ use
> "override" as an identifier as well as a contextual keyword, does not
> make it a good idea).
 
It may be some important API that has contained such identifier for
decade. Authors have full right to complain that the members of
standard committee now try to get unfair advantage over their product
by breaking their API in new compiler. Hostility of authors (and
users) of it should not be taken lightly. ;)
drew@furrfu.invalid (Drew Lawson): Apr 23 01:41PM

In article <mha67m$1h8$1@dont-email.me>
>the code appropriately when moving to C++11 (just because you /can/ use
>"override" as an identifier as well as a contextual keyword, does not
>make it a good idea).
 
Sure, it is a bad idea now. But it was reasonable in earlier versions.
 
It took at least a year of C++ before I stopped trying to use "new"
as a variable name. It was a very obvious and useful name for a
dynamically created item. I also had to break the habit of using
the pair "this" and "that."
 
I still occasionally run into head-slap mistakes like that, especially
when I have my head deep in the vocabulary of the problem domain
(class, public, float, switch -- lots of valid English words to
trip on), rather than the programming language.
 
--
Drew Lawson | And to those who lack the courage
| And say it's dangerous to try
| Well they just don't know
| That love eternal will not be denied
jt@toerring.de (Jens Thoms Toerring): Apr 23 12:16AM

> 06_loading_a_texture
> /usr/bin/ld: cannot find -ldevIL
> collect2: error: ld returned 1 exit status
 
From your previous post:
 
> these libraries [are] located in /usr/lib/i386-linux-gnu/
 
Are you really on a 32-bit (i386) system? If not the linker
is looking for a 64-bit library and you either have to ex-
plicitely build a 32-bit executable (and then, of course,
you need 32-bit versions of all necessary libraries) - or
you have to get the 64-bit version of the libraries not
found.
Regards, Jens
--
\ Jens Thoms Toerring ___ jt@toerring.de
\__________________________ http://toerring.de
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: