From: Patrick H. <pa...@in...> - 2004-10-27 23:39:12
|
Patrick Hartling wrote: > Patrick Hartling wrote: > >> Another problem with this is that it doesn't compile with Visual C++ 7.0. > > > Since I haven't found any viable workarounds for this problem, I started > working on patches to GMTL that make the vector expression code optional > based on whether the compiler supports the language features used [*]. > Fortunately for me, Allen's tendency to leave old code in comments > has paid off in a lot of places in terms of the speed at which I can > apply #ifdef's. This means that users of compilers that can't handle > the more advanced template code won't be able to get the performance > boost of the expression templates, but at least their code will work. I have finished the patches that allow the metaprogramming features to be conditionally disabled at compile time. With my changes, the metaprogramming stuff is only disabled with Visual C++ 7.0 as I have not encountered any other compilers that cannot handle the code. I have attached the patches for review purposes. As I noted in my previous message, most of the old code was still there, just commented out. That made fixing the Visual C++ 7.0 problems quite simple. I have done my best to strip out all the new metaprogramming code in the Visual C++ 7.0 case, but the test suite is not really set up for use with Visual C++ 7.0. I made my patches incrementally by building VR Juggler from CVS and all of its sample and test applications (except osgNav and OpenSGNav). > [*] I am also concerned that the MIPSpro C++ Compiler 7.3.1.x may not be > able to handle this code, but I haven't tried it yet due to time > constraints. I have no idea about how well the Sun or HP compilers > handle any of GMTL. I am happy to report that the MIPSpro C++ Compiler 7.3.1.3m has no problems with the latest GMTL code. So, are there any objections to me committing the attached patch? -Patrick >> Allen Bierbaum wrote: >> >>> I just merged my work on expression templates from the work branch >>> into the CVS head of GMTL. >>> >>> This is a *major* feature addition and re-working of the VecBase (Vec >>> & Point) classes and all operators that work on them. >>> >>> This change uses expression templates to remove temporary objects >>> from expression evaluation and potentially allow compilers to better >>> optimize the code. >>> >>> For example, with the previous code: >>> >>> vec1 = vec2 + vec3 + (vec4 * 6) >>> >>> that would have created 3 temporary vectors. In the new code the >>> expression templates output code that directly computes the final >>> value from the given operands. This has shown at least a 2x >>> performance increase in my tests. >>> >>> The code is far from perfect though and could definitely be optimized >>> much further. (especially by someone that knows intel assembly and >>> has some patience) >>> >>> There is one common compiler error to be aware of. It is not >>> possible to pass expression templates where VecBase/Vec/Point objects >>> are expected. >>> >>> Details: >>> >>> GMTL makes extensive use of expression templates. These templates >>> come into play when evaluating statement such as: >>> >>> gmtl::Vec3f vec1, vec2, vec3; >>> vec1 = vec2 + (vec3 * 6.0); >>> >>> When evaluating the expression on the second line, GMTL creates an >>> expression template tree to fully evaluate this expression when = is >>> called. The details of this process are normally hidden from the >>> user, but can come to the forefront when a method expects a Vec or >>> Point argument and is passed an expression. For example: >>> >>> void myMethod(gmtl::Vec3f vec) >>> { ... } >>> >>> gmtl::Vec3f vec1, vec2; >>> >>> myMethod(vec1); // Works correctly >>> myMethod(vec1 + vec2); // Fails to compile >>> >>> The reason the second line fails to compile is that the type for >>> "vec1 + vec2" is not a Vec3f. It is an expression template that >>> describes how to sum two Vec3f's. (You may expect an autoconversion >>> to happen, but it does not because of template argument deduction >>> rules). >>> >>> There are two solutions to this, either explicitly construct a temporary >>> object to pass to the method (which is what an auto conversion would >>> do anyway) or write the method to handle expression templates. This >>> second option is not difficult, but does require a further >>> understanding of GMTL then is documented here. >>> >>> Here is how the first option could be used: >>> >>> myMethod(gmtl::Vec3f(vec1 + vec2)); // Creates a temporary to >>> pass in >>> >>> >>> >>> In closing: Give the code and try and let me know what you think. :) >>> >>> >>> -Allen -- Patrick L. Hartling | VP Engineering, Infiscape Corp. PGP: http://tinyurl.com/2msw3 | http://www.infiscape.com/ |