Are there optimized C ++ compilers for using templates?

C ++ templates have been a blessing in my daily work because of its power. But you cannot ignore the (very very very long) compilation time that results from the heavy use of templates (hi-meta programming and Boost libraries). I read and tried quite a few possibilities for manual reorganization and modification of the template code so that it compiles as quickly as possible.

Now I'm wondering if there are C ++ compilers that try and minimize the time needed to interpret the template classes. I may be mistaken, but I feel that the compilers I know have only added pattern interpretation to their previous versions.

My questions:

  • Is the C ++ template code so complicated to interpret that optimizing it a bit? (I really doubt that)
  • Are there C ++ compilers that really optimize the interpretation of "C ++ templates"?
  • Are there any projects to develop a new generation of C ++ compilers that would optimize this?
  • If you participated in such a project, what would your recommendations be?
+22
c ++ compiler-construction templates
Feb 24 '09 at 15:54
source share
8 answers

G ++ 4.5 seems to have made tremendous progress in working with templates. Here are two inevitable changes.

  • "When you print a g ++ class template specialization name, there will now be no template argument that comes from the default template arguments." This can be considered a subtle modification, but it will have a huge impact on development using C ++ templates (ever heard of unreadable error messages ...? No more!)

  • "The compilation time of code using templates should now scale linearly with the number of instances, not quadratically." This will seriously undermine compile-time arguments against using C ++ templates.

See gnu for details.

In fact, I'm already curious, there are still problems with C ++ templates! Mmm, yes there is, but now focus on the bright side!

+4
Apr 19 '10 at 11:44
source share
— -

I expect the compiled template code to be accelerated with the presence of variational templates / rvalue values. Today, if we want to write code for a template that does something during compilation, we are abusing language rules. We create dozens of overloads and specialized templates that lead to what we want, but not in a way that tells the compiler our intent. Thus, little can be reduced for the compiler during assembly. See Motivation for Variable Templates.

Are there any projects to develop a new generation of C ++ compilers that would optimize this?

Yes, there is CLang , which is the C language interface for the LLVM compiler infrastructure. Both CLang and LLVM are encoded using C ++. CLang developers include Douglas Gregor, author of several C ++ 1x language suggestions, such as custom templates and concepts. For reference, see This Douglas Gregor Test Talking About GCC

http://www.freeimagehosting.net/uploads/a2e6f1dc27.png

Below are some quick performance results for creating templates in Clang and GCC 4.2. The test is very simple: measure the compilation time (-fsyntax-only) for a translation unit that calculates the Nth Fibonacci number using the template metaprogram. Clang seems to scale linearly (or close to it) with the number of instances. And, although you cannot see it in the diagram, Clang is slightly more 2x faster than GCC at the beginning ( Fibonacci<100> ).

CLang is still at the beginning of the day , but I think it has a good chance of becoming a great C ++ compiler.

+14
Feb 25 '09 at 1:51
source share

This really is not the answer to your question. These are more observations on the side.

I am also not a lawyer in C ++, and therefore I could be outside the database with some details.

But a gross idea must be right.

The main reason C ++ compilers take so long to compile template metaprograms is due to how template metaprograms are defined.

They are not specified directly as the code that you want the compiler to execute at compile time. Take an example of calculating the length of a type list.

If you could write code like this:

 compile_time size_t GetLength(TypeList * pTypeList) { return DoGetLength(pTypeList, 0); } compile_time size_t DoGetLength(TypeList * pTypeList, size_t currentLength) { if (pTypeList) { return DoGetLength(pTypeList->Next, ++currentLength); } else { return currentLength; } } 

Here are some of them that were compiled separately from the code in which it was used, and were exposed to the language through some syntax, then the compiler will be able to execute it very quickly.

This is just a call to a simple recursive function.

You can create a language that allows such things. Most of them that do this (e.g. lisp) are dynamically typed, but this can be done with a static set. However, this is unlikely to ever be what you see in C ++.

However, the problem in C ++ is that the code is written as:

 template <typename First, typename Second> struct TypeList { typedef First Head; typedef Second Tail; }; template <> struct ListSize<NullType> { enum { size = 0 }; }; template <typename Head, typename Tail> struct ListSize<TypeList<Head, Tail> > { enum { size = 1 + ListSize<Tail>::size }; }; 

For the compiler to “execute” the metaprogram, it must:

  • Build a dependency graph for the initial values ​​of the size value "size"
  • Build a template type for each edge in a graph
  • Bind all characters referenced by each template type built
  • Topologically sort the dependency graph
  • Go through the graph and evaluate the constants

This is much more expensive than just running the recursive O (N) algorithm.

In the worst case, there will be something like O (N * M * L), where N is the length of the list, M is the nesting level of the area, and L is the number of characters in each area.

My advice will be to minimize the amount of C ++ template metaprogram code that you use.

+9
Feb 25 '09 at 1:42
source share

The main problem with the templates is as follows:

You cannot (usually) separate the definition of your template from its declaration and place it in a .cpp file.

Corollary: Everyting is in the header files. Whenever you include a header, you include all the code, which under normal circumstances will be perfectly divided into .cpp files and compiled separately. Each compilation unit includes several headers, and therefore with templates, each compilation module contains a lot of code or almost all of your project with headers included.

If this is your problem, look here for a related question:

  • Templates: use forward declarations to reduce compilation time?

He received a very good answer that solves this problem .

Basically, it involves creating instances that you need once, and compiling them into an object file. You can later associate with it, and you do not need to include this code everywhere. It is split into a compiled object file. Note. This only makes sense if you only use a few instances of your templates (for example, you only need MyType<int> and MyType<double> in your program).

It uses the g++ -fno-implicit-templates flag.

This method is so useful that I think it should be included in C ++ faq: [35.12] Why can't I separate the definition of my class templates from it and put it in a .cpp file?

+7
Feb 25 '09 at 1:56
source share

This is not the answer you need, but Walter Bright was the main developer of the first native C ++ compiler and optimized C ++ complier. In the end, he wrote his own programming language called D. This is basically an improvement in C ++ and handles templates better.

I do not know the C ++ compiler that it optimized for using the template.

+2
Feb 24 '09 at 16:00
source share

a gold linker can help reduce connection times by about 5 times, which can reduce overall compilation time. This is especially useful since binding cannot be parallelized in the same way as compilation.

(Not a direct answer, but hopefully this is helpful).

+2
Jul 31 '09 at 12:57
source share

Try Incredibuild . This drastically reduces compilation / build time.

This product basically allows Visual C ++ to build on multiple computers in your organization, taking advantage of downtime cycles. I used Incredibuild on huge projects (500 kloc) with lots of template code and got good acceleration during build.

+1
Feb 24 '09 at 16:57
source share

I think the templates themselves are not too complex on their own. We will see when concepts are introduced in C ++ 0x, etc., but for now, templates are just (almost) macros, so the real problem is not if you optimized C ++ compilers for templates. The problem is that the templates generate such huge code during compilation, which makes compilation slower.

0
Feb 24 '09 at 16:56
source share



All Articles