 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Hanyou Chu Guest
|
Posted: Fri Nov 12, 2004 3:07 pm Post subject: Why is the std::complex class so complex? |
|
|
This question is probably for P.J. Plauger who supplied
stl library for microsoft and gcc. The operator * for
two complex numbers is written as (not literarily)
complex operator*(const complex &a,const complex& b)
{
complex t=a;
t *= b;
return t;
}
It prevents Microsoft compilers(vc 6 and 7) from optimizing it in such a
way that it slows the computations down by more than a factor
of two(probably three). The Intel compiler is much better at
optimizing this.
My question is why isn't it written in the following way instead:
complex operator*(const complex &a,const complex& b)
{
return complex(a.real()*b.real()-a.imag()*b.imag(),
a.real()*b.imag()+a.imag()*b.real());
}
People suggested transforming the above into 3 multiplications instead
of 4, but it requires two temporaries, and as a result the code is
slower.
The other thing is related to the complex exponential function,
which is again written in such a way that the calculation is slowed
down by a factor of two.
As calculational speed is critical to our product, this is unacceptible.
I am attempted to write my own complex class, but that would defeat the
purpose of having a stl library.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hanyou Chu Guest
|
Posted: Sat Nov 13, 2004 2:48 am Post subject: Re: Why is the std::complex class so complex? |
|
|
I forgot to add that the code really looks too complicated.
Inline functions call identical inline functions with another
name.
We finally decided to look at the assembly code, it turns out
that the MS compiler is not able to inline the multiplications
due to multilayer function calls.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Frank Birbacher Guest
|
Posted: Sun Nov 14, 2004 5:01 am Post subject: Re: Why is the std::complex class so complex? |
|
|
Hi!
Hanyou Chu wrote:
| Quote: | The operator * for
two complex numbers is written as (not literarily)
complex operator*(const complex &a,const complex& b)
{
complex t=a;
t *= b;
return t;
}
|
That's a reasonable implementation.
| Quote: | It prevents Microsoft compilers(vc 6 and 7) from optimizing it in such a
way that it slows the computations down by more than a factor
of two(probably three). The Intel compiler is much better at
optimizing this.
|
Back luck for MS here.
| Quote: | My question is why isn't it written in the following way instead:
complex operator*(const complex &a,const complex& b)
{
return complex(a.real()*b.real()-a.imag()*b.imag(),
a.real()*b.imag()+a.imag()*b.real());
}
|
It stems from a common design principle: Avoid redundant code.
Because if you did something wrong when implementing the
multiplication, then you probably did it wrong in two places
(operator * and *=). By calling one from the other, you avoid
this. See, operator * is just a convinience function.
| Quote: | As calculational speed is critical to our product, this is unacceptible.
I am attempted to write my own complex class, but that would defeat the
purpose of having a stl library.
|
If speed is critical, then change *your* code to use operator *=
instead. This will save you some temporaries.
Frank
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
M Jared Finder Guest
|
Posted: Sun Nov 14, 2004 10:32 am Post subject: Re: Why is the std::complex class so complex? |
|
|
Hanyou Chu wrote:
| Quote: | The other thing is related to the complex exponential function,
which is again written in such a way that the calculation is slowed
down by a factor of two.
As calculational speed is critical to our product, this is unacceptible.
I am attempted to write my own complex class, but that would defeat the
purpose of having a stl library.
|
Complex is a very simple class to write, so if you really need the speed
improvements, why not write a custom <complex>? There is a lot of
functionality, but it should be relatively straightforward to implement;
no more than a few days work. If your new implementation complies with
the standard, then other programmers still do not need to learn Yet
Another API.
-- MJF
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Peter Koch Larsen Guest
|
Posted: Sun Nov 14, 2004 4:55 pm Post subject: [OT] Re: Why is the std::complex class so complex? |
|
|
"Hanyou Chu" <hchu (AT) thermawave (DOT) com> skrev i en meddelelse
news:ceee3b79.0411121201.5dfd65e8 (AT) posting (DOT) google.com...
| Quote: | I forgot to add that the code really looks too complicated.
Inline functions call identical inline functions with another
name.
We finally decided to look at the assembly code, it turns out
that the MS compiler is not able to inline the multiplications
due to multilayer function calls.
|
This has also been my experience with VC++ 6.0: deeply nested inline
functions are not inlined however simple they are. I believe that a switch
to 7.1 would fix that. You could also declare the functions __forceinline
(not sure this is exact spelling, so you have to look it up). This is of
course inconvenient if you have to modify system-headers, but perhaps
Dinkumware has a patch?
Kind regards
Peter Koch Larsen
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Sun Nov 14, 2004 5:00 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
Hanyou Chu wrote:
| Quote: | I forgot to add that the code really looks too complicated.
Inline functions call identical inline functions with another
name.
We finally decided to look at the assembly code, it turns out
that the MS compiler is not able to inline the multiplications
due to multilayer function calls.
|
You question is MS specific, this is the wrong place for that.
You should post your question to microsoft.public.vc.stl.
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Glen Low Guest
|
Posted: Sun Nov 14, 2004 8:38 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
| Quote: | My question is why isn't it written in the following way instead:
complex operator*(const complex &a,const complex& b)
{
return complex(a.real()*b.real()-a.imag()*b.imag(),
a.real()*b.imag()+a.imag()*b.real());
}
|
Most people recommended implementing operator* in terms of operator*=,
but even on a modern compiler like gcc 3.3, it pessimizes
temporary-laden code as a result e.g.
complex a = b * c + d * e;
has at least 2 temporaries that are slowed down by having the
operator* defined in terms of operator*=. Do it the other way around
and it becomes much faster, likely because the compiler knows it
doesn't need to push the values back to memory and simply keeps them
in registers ("enregistration").
| Quote: | People suggested transforming the above into 3 multiplications instead
of 4, but it requires two temporaries, and as a result the code is
slower.
|
Not necessarily. If the temporaries are enregistered you don't really
pay a thing.
I know gcc 3.3 properly enregisters structs with single members and
inbuilt types.
| Quote: | The other thing is related to the complex exponential function,
which is again written in such a way that the calculation is slowed
down by a factor of two.
As calculational speed is critical to our product, this is unacceptible.
I am attempted to write my own complex class, but that would defeat the
purpose of having a stl library.
|
Hmm... I'm in the process of writing an Altivec-enhanced version of
the valarray and complex implementations in my macstl library. I
haven't gotten round to doing the intended optimization in SSE2 yet,
but the Altivec-enhanced multiply is already 1.75x faster than scalar
multiply on complex<float>.
Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mickey Moore Guest
|
Posted: Mon Nov 15, 2004 11:41 am Post subject: Re: Why is the std::complex class so complex? |
|
|
It seems to me that this is a case of just using the canonical idiom
("Implement operator@ in terms of operator@=") instead of bothering
to actually *think* about the best implementation or understand the
requirements of the typical client of the class.
The canonical idiom is almost always The Right Thing To Do, but when
it's not, then it shouldn't be done!
Your question highlights an implementation issue, but the standard
for complex<T> itself contains an instance of doing the Canonical
Thing instead of the Right Thing. After working on a recent project,
it's become very clear to me that complex<T> should have been
implemented with public data members (named real and imag).
It's too late to do that now of course. ("Get your interfaces right
first. If you get the interface wrong you may never be allowed to fix
it." -- Sutter) At the very least, complex<T> needs a way to handle
the real and imaginary parts separately. Instead, the class remains
broken, two years after the defect was formally publicized! (See
library issue #387.) (Fortunately, the g++ library contains a non-
standard extension which implements suggested fix #2 in the
standard's document n1589, which I've come to believe is the only
acceptable solution to the second subissue of issue #387.)
| Quote: | As calculational speed is critical to our product, this is unacceptible.
|
Calculation speed is almost always critical when dealing with
mathematical primitives in numerical work.
---------------------------------------------
Mitchell G. (Mickey) Moore, Ph.D. (Physics)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
chris Guest
|
Posted: Mon Nov 15, 2004 11:20 pm Post subject: [OT] Re: Why is the std::complex class so complex? |
|
|
Glen Low wrote:
| Quote: | My question is why isn't it written in the following way instead:
complex operator*(const complex &a,const complex& b)
{
return complex(a.real()*b.real()-a.imag()*b.imag(),
a.real()*b.imag()+a.imag()*b.real());
}
Most people recommended implementing operator* in terms of operator*=,
but even on a modern compiler like gcc 3.3, it pessimizes
temporary-laden code as a result e.g.
complex a = b * c + d * e;
has at least 2 temporaries that are slowed down by having the
operator* defined in terms of operator*=. Do it the other way around
and it becomes much faster, likely because the compiler knows it
doesn't need to push the values back to memory and simply keeps them
in registers ("enregistration").
|
Sorry for the slightly off-topic post, but for those who are tempted to
start fiddling with their code due to this lack of optimisation, it's
worth noting that gcc's current CVS version, and therefore the upcoming
gcc 4 will optimise all the temporaries away in this statement.
Chris
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hanyou Chu Guest
|
Posted: Wed Nov 17, 2004 11:58 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
M Jared Finder <jared (AT) hpalace (DOT) com> wrote
| Quote: | Hanyou Chu wrote:
The other thing is related to the complex exponential function,
which is again written in such a way that the calculation is slowed
down by a factor of two.
As calculational speed is critical to our product, this is unacceptible.
I am attempted to write my own complex class, but that would defeat the
purpose of having a stl library.
Complex is a very simple class to write, so if you really need the speed
improvements, why not write a custom <complex>? There is a lot of
functionality, but it should be relatively straightforward to implement;
no more than a few days work. If your new implementation complies with
the standard, then other programmers still do not need to learn Yet
Another API.
I am aware of that, we already did write our own class. I just assumed that |
the stl implementation was high quality.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hanyou Chu Guest
|
Posted: Wed Nov 17, 2004 11:58 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
| Quote: | Most people recommended implementing operator* in terms of operator*=,
but even on a modern compiler like gcc 3.3, it pessimizes
temporary-laden code as a result e.g.
complex a = b * c + d * e;
has at least 2 temporaries that are slowed down by having the
operator* defined in terms of operator*=. Do it the other way around
and it becomes much faster, likely because the compiler knows it
doesn't need to push the values back to memory and simply keeps them
in registers ("enregistration").
gcc is not particularly good at optimizing code. On a 64 bit opteron |
the 64bit code generated by gcc is about twice as slow compared to the same
code generated on windows running 32bit operating system.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hanyou Chu Guest
|
Posted: Wed Nov 17, 2004 11:59 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
| Quote: | It stems from a common design principle: Avoid redundant code.
Because if you did something wrong when implementing the
multiplication, then you probably did it wrong in two places
(operator * and *=). By calling one from the other, you avoid
this. See, operator * is just a convinience function.
It is so simple that there is no reason not to. |
| Quote: |
If speed is critical, then change *your* code to use operator *=
instead. This will save you some temporaries.
It would become unreadable. |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Hanyou Chu Guest
|
Posted: Thu Nov 18, 2004 12:07 am Post subject: Re: Why is the std::complex class so complex? |
|
|
Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> wrote
| Quote: | You question is MS specific, this is the wrong place for that.
You should post your question to microsoft.public.vc.stl.
gcc uses the same stl implementation. |
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
P.J. Plauger Guest
|
Posted: Thu Nov 18, 2004 12:15 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
"Hanyou Chu" <hchu (AT) thermawave (DOT) com> wrote
| Quote: | Alberto Barbati <AlbertoBarbati (AT) libero (DOT) it> wrote in message
news:
You question is MS specific, this is the wrong place for that.
You should post your question to microsoft.public.vc.stl.
gcc uses the same stl implementation.
|
No, it doesn't.
P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Mickey Moore Guest
|
Posted: Fri Nov 19, 2004 3:29 pm Post subject: Re: Why is the std::complex class so complex? |
|
|
| Quote: | gcc uses the same stl implementation [as MS].
No, it doesn't.
P.J. Plauger
|
PJP is of course correct; in fact, I'm rather amazed at how
differently the complex classes are implemented!
However, the OP's complaint, that operator* is implemented in terms
of operator*=, is true of both the MS and gcc3 versions.
I came across this just recently in Sutter and Alexandrescu's new
book 'C++ Coding Standards': Item 27 is 'Prefer the canonical forms
of arithmetic and assignment operators', which among other things
means 'implement operator@ in terms of operator@='. But their
exceptions clause reads: "In some cases (e.g., operator*= on complex
numbers), an operator might mutate its left-hand side so
significantly that it can be more advantageous to implement
operator*= in terms of operator* rather than the reverse."
In mild defense of gcc3's complex, they do admit in the header file
several times that "This is a grammar school implementation.". They
also state that it is not conforming, though it's not obvious how.
(Does adding an extension make something formally non-conforming even
if all the standard defined behavior is correct?)
---------------------------------------------
Mitchell G. (Mickey) Moore, Ph.D. (Physics)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|