
"Matthias Troyer" <troyer@itp.phys.ethz.ch> wrote in message news:B1F6950B-29D5-4F04-BDC0-7D6E7A56038F@itp.phys.ethz.ch...
On Aug 20, 2006, at 4:19 PM, Andy Little wrote:
T temp = 0.5; temp *= a; temp *= t; temp *= t; s += temp;
This is completely wrong. a is a vector and you thus cannot multiply it to the scalar 0.5
OK. OTOH it prompted me to start writing another performance test. Its not finished yet, but in contrast to what I said it appears that Quan types perform quite well in comparison to inbuilts in this case ( based on two_param-branch in quan CVS which has had vectors improved relative to quan-0_1_0). As always one should be very careful with these tests!. In this case, maybe, because the Quan expression is evaluated first, it grabs the better registers. Anyway here is the source so far. I need to add some timing, but the assembly output from VC8 suggests that Quan does quite well in this particular case. It may mean I could write the double expression better too of course #include <quan/three_d/out/vect.hpp> #include <quan/out/velocity.hpp> #include <quan/out/acceleration.hpp> #include <quan/out/time.hpp> #include <quan/out/length.hpp> #include <quan/fixed_quantity/io/input.hpp> #include <fstream> /* vector of double v vector of quantities */ int main() { typedef quan::acceleration::m_per_s2 accel; typedef quan::velocity::m_per_s velocity; typedef quan::length::m length; using quan::three_d::vect; typedef vect<accel> accel_vect; typedef vect<velocity> velocity_vect; typedef vect<length> distance_vect; accel_vect a(accel(333.),accel(444.),accel(555.)); velocity_vect u(velocity(666.),velocity(777.), velocity(888.)); quan::time::s t(.5); // nuke the optimiser { std::ofstream qos("quantity.txt"); qos << a.x << '\n' << a.y << '\n' << a.z <<'\n'; qos << u.x << '\n' << u.y << '\n' << u.z <<'\n'; qos << t <<'\n'; } { std::ifstream qis("quantity.txt"); qis >> a.x >> a.y >> a.z >> u.x >>u.y >> u.z >> t; } distance_vect s = u * t; distance_vect temp = a * t * t; temp *=0.5; s += temp; std::cout << "quantity vect result= " << s <<'\n'; // double version typedef vect<double> vectd; vectd a1(333.,444.,555.), u1(666.,777.,888.); double t1 = 0.5; // nuke the optimiser { std::ofstream os("double.txt"); os << a1.x << '\n' << a1.y << '\n' << a1.z <<'\n'; os << u1.x << '\n' << u1.y << '\n' << u1.z <<'\n'; os << t1 <<'\n'; } { std::ifstream is("double.txt"); is >> a1.x >> a1.y >> a1.z >> u1.x >>u1.y >> u1.z >> t1; } vectd s1 = u1; s1 *= t1; vectd temp1 = a1; temp1 *= 0.5; temp1 *= t1; temp1 *=t1; s1 += temp1; std::cout << "double vect result= " << s1 <<'\n'; } chopped output of respective calcs in VC* with a lot of optimsiation /////////////////////// quan calc ; 40 : distance_vect s = u * t; fld QWORD PTR _u$[esp+536] fld QWORD PTR _t$[esp+520] add esp, 4 fmul ST(1), ST(0) ; 41 : distance_vect temp = a * t * t; ; 42 : temp *=0.5; ; 43 : s += temp; ; 44 : ; 45 : std::cout << "quantity vect result= " << s <<'\n'; push OFFSET $SG-215 fld QWORD PTR _u$[esp+528] push OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout fmul ST(0), ST(1) fld QWORD PTR _u$[esp+524] fmul ST(0), ST(2) fld QWORD PTR _a$[esp+540] fmul ST(0), ST(3) fld QWORD PTR _a$[esp+532] fmul ST(0), ST(4) fld QWORD PTR _a$[esp+524] fmul ST(0), ST(5) fxch ST(2) fmul ST(0), ST(5) fxch ST(1) fmul ST(0), ST(5) fxch ST(2) fmulp ST(5), ST(0) fld QWORD PTR __real@3fe0000000000000 fmul ST(5), ST(0) fmul ST(2), ST(0) fmulp ST(1), ST(0) fxch ST(2) faddp ST(4), ST(0) fxch ST(3) fstp QWORD PTR _s$[esp+524] fxch ST(2) faddp ST(1), ST(0) fstp QWORD PTR _s$[esp+532] faddp ST(1), ST(0) fstp QWORD PTR _s$[esp+540] call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@ // double calc ; 65 : vectd s1 = u1; fld QWORD PTR _u1$[esp+520] fst QWORD PTR _s1$[esp+520] add esp, 4 fld QWORD PTR _u1$[esp+524] ; 66 : s1 *= t1; ; 67 : vectd temp1 = a1; ; 68 : temp1 *= 0.5; ; 69 : temp1 *= t1; ; 70 : temp1 *=t1; ; 71 : s1 += temp1; ; 72 : ; 73 : std::cout << "double vect result= " << s1 <<'\n'; push OFFSET $SG-218 fld QWORD PTR _u1$[esp+536] push OFFSET ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::cout fld QWORD PTR _t1$[esp+524] fmul ST(3), ST(0) fmul ST(2), ST(0) fmul ST(1), ST(0) fld QWORD PTR _a1$[esp+524] fst QWORD PTR _temp1$[esp+524] fld QWORD PTR _a1$[esp+532] fld QWORD PTR _a1$[esp+540] fld QWORD PTR __real@3fe0000000000000 fmul ST(3), ST(0) fmul ST(2), ST(0) fmulp ST(1), ST(0) fxch ST(2) fmul ST(0), ST(3) fxch ST(1) fmul ST(0), ST(3) fxch ST(2) fmul ST(0), ST(3) fxch ST(1) fmul ST(0), ST(3) fxch ST(2) fmul ST(0), ST(3) fxch ST(1) fmulp ST(3), ST(0) fxch ST(1) faddp ST(5), ST(0) fxch ST(4) fstp QWORD PTR _s1$[esp+524] fxch ST(3) faddp ST(2), ST(0) fxch ST(1) fstp QWORD PTR _s1$[esp+532] faddp ST(1), ST(0) fstp QWORD PTR _s1$[esp+540] call ??$?6U?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ; std::operator<<<std::char_traits<char> > mov esi, eax ///////////////////////
In fact you can do in place addition of quantities of course, but not multiplication, or at least not without low level manipulations.
It sounds like I am arguing against my own library. I'm not, but I am pointing out that there are different considerations when using quantities and you may not ( in fact probably wont) get as good a performance as from using inbuilt floats. Overall Quan is much more fun to use than floats though, and I have enjoyed using it so far where possible..
In fact it seems to me that you are much better off using a nice linear algebra library that makes use of expression templates.
To be honest you have lost me here. Are you now saying it would be better for me to ditch Quan and start writing a linear algebra library for floats that uses E.T? There are a few of those around already. OTOH If an E.T library is any good then it should be possible to get Quan to work with it. However in the case of existing linear algebra libraries, they are all (including AFAICS MTL2) just set up for floats and possibly numeric UDT's.
FWIW I do see the difference between using quantities and floats as very coarsely equivalent to the difference between using an assembly language and (say) C. When using quantities you are effectively using a higher level language than standard C ++ using floats.
I disagree since the units part is optimized away at compile time and you should be left just with pure floating point operations at the end of the day.
That is a different issue . Sure it is possible for the compiler to optimise the details of a higher level language and I am doing what I can to make sure it does so, but that doesnt change the fact that it's a higher level language. And as a user I have found Quan is a lot of fun to use. The issue is always going to be a lack of supporting libraries. For me though it is a good learning process to try to understand quaternions and more about linear algebra in general by trying to write some supporting librraies for quan. regards Andy Little