Cordic

D

Dave Townsend

Hi,

I'm working on an implementation of the CORDIC
algorithm for a library of functions.

One of the benefits of the CORDIC algorithm is that you
can implement it with simple additions of numbers and
division of (doubles) by powers of two. However, there
doesn't seem to be any mechanism in the C/C++ language
to direct the compiler to do this efficient form of division,
any ideas, experiences out there please?

dave
 
V

Victor Bazarov

Dave said:
I'm working on an implementation of the CORDIC
algorithm for a library of functions.

One of the benefits of the CORDIC algorithm is that you
can implement it with simple additions of numbers and
division of (doubles) by powers of two. However, there
doesn't seem to be any mechanism in the C/C++ language
to direct the compiler to do this efficient form of division,
any ideas, experiences out there please?

I am curious about how you've arrived to the [apparent] conclusion
that whatever the compiler does (without your direction) is somehow
inefficient.

V
 
D

Dave Townsend

Victor Bazarov said:
Dave said:
I'm working on an implementation of the CORDIC
algorithm for a library of functions.

One of the benefits of the CORDIC algorithm is that you
can implement it with simple additions of numbers and
division of (doubles) by powers of two. However, there
doesn't seem to be any mechanism in the C/C++ language
to direct the compiler to do this efficient form of division,
any ideas, experiences out there please?

I am curious about how you've arrived to the [apparent] conclusion
that whatever the compiler does (without your direction) is somehow
inefficient.

V
I happend to have looked at the assembly code generated - albeit in Debug
mode on VC6.

9: double d = 100.00;
00401028 mov dword ptr [ebp-8],0
0040102F mov dword ptr [ebp-4],40590000h
10: double e = d / 2 ;
00401036 fld qword ptr [ebp-8]
00401039 fdiv qword ptr [__real@8@40008000000000000000 (00423ff0)]
0040103F fstp qword ptr [ebp-10h]
11: double f = d / 2.5;
00401042 fld qword ptr [ebp-8]
00401045 fdiv qword ptr [__real@8@40008000000000000000 (00423030)]
0040104B fstp qword ptr [ebp-18h]
 
T

TB

Dave Townsend skrev:
Victor Bazarov said:
Dave said:
I'm working on an implementation of the CORDIC
algorithm for a library of functions.

One of the benefits of the CORDIC algorithm is that you
can implement it with simple additions of numbers and
division of (doubles) by powers of two. However, there
doesn't seem to be any mechanism in the C/C++ language
to direct the compiler to do this efficient form of division,
any ideas, experiences out there please?
I am curious about how you've arrived to the [apparent] conclusion
that whatever the compiler does (without your direction) is somehow
inefficient.

V
I happend to have looked at the assembly code generated - albeit in Debug
mode on VC6.

Are you trashing a compiler as inefficient based on the debug code?
9: double d = 100.00;
00401028 mov dword ptr [ebp-8],0
0040102F mov dword ptr [ebp-4],40590000h
10: double e = d / 2 ;
00401036 fld qword ptr [ebp-8]
00401039 fdiv qword ptr [__real@8@40008000000000000000 (00423ff0)]
0040103F fstp qword ptr [ebp-10h]
11: double f = d / 2.5;
00401042 fld qword ptr [ebp-8]
00401045 fdiv qword ptr [__real@8@40008000000000000000 (00423030)]
0040104B fstp qword ptr [ebp-18h]

And what do you deem as a more efficient substitute?
 
D

Dave Townsend

TB said:
Dave Townsend skrev:
Victor Bazarov said:
Dave Townsend wrote:
I'm working on an implementation of the CORDIC
algorithm for a library of functions.

One of the benefits of the CORDIC algorithm is that you
can implement it with simple additions of numbers and
division of (doubles) by powers of two. However, there
doesn't seem to be any mechanism in the C/C++ language
to direct the compiler to do this efficient form of division,
any ideas, experiences out there please?
I am curious about how you've arrived to the [apparent] conclusion
that whatever the compiler does (without your direction) is somehow
inefficient.

V
I happend to have looked at the assembly code generated - albeit in Debug
mode on VC6.

Are you trashing a compiler as inefficient based on the debug code?
9: double d = 100.00;
00401028 mov dword ptr [ebp-8],0
0040102F mov dword ptr [ebp-4],40590000h
10: double e = d / 2 ;
00401036 fld qword ptr [ebp-8]
00401039 fdiv qword ptr [__real@8@40008000000000000000 (00423ff0)]
0040103F fstp qword ptr [ebp-10h]
11: double f = d / 2.5;
00401042 fld qword ptr [ebp-8]
00401045 fdiv qword ptr [__real@8@40008000000000000000 (00423030)]
0040104B fstp qword ptr [ebp-18h]

And what do you deem as a more efficient substitute?

Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to investigate the
benefits of using a CORDIC algorithm. I was looking for a "shift" type
operation which would divide a double by a power of two which presumably
would be more efficient than a general purpose division algorithm. If people
have some useful comments, please post.
 
M

Marek Vondrak

Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to investigate
the
benefits of using a CORDIC algorithm. I was looking for a "shift" type
operation which would divide a double by a power of two which presumably
would be more efficient than a general purpose division algorithm. If
people
have some useful comments, please post.

Assuming that floating point values are stored in a certain format (ie. IEEE
floats) you can implement your own shift operations that would modify the
mantisa fields of the binary representations directly. This would obviously
be non-portable and certainly not guaranteed to be faster than the
corresponding multiplications/division performed on the FPU.

-- Marek
 
V

Victor Bazarov

Dave said:
[..]
Did everybody get out of bed on the wrong side this morning?

Not me. You sound like that, however. I was just asking where you
get your information about the alleged inefficiency.
I'm not trashing anybody or any compiler, I'm just trying to
investigate the benefits of using a CORDIC algorithm.

I have no idea what that is. C++ Standard doesn't define one, so
you might actually mention some source of information (besides the
obvious Google) about your subject.
I was looking
for a "shift" type operation which would divide a double by a power
of two which presumably would be more efficient than a general
purpose division algorithm. If people have some useful comments,
please post.

Dividing by a power of two the most efficiently would be subtracting
from the exponent stored in some bits of the FP number. Is that what
you're trying to do? Essentially you need to extract the exponent
(see 'frexp' function), subtract and then recombine the new exponent
with the mantissa (see 'ldexp' function).

V
 
C

Cesar Rabak

Dave said:
[snipped]
Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to investigate
the benefits of using a CORDIC algorithm. I was looking for a "shift" type
operation which would divide a double by a power of two which presumably
would be more efficient than a general purpose division algorithm. If
people have some useful comments, please post.

Dave,

For start of the discourse, why in the Earth you think it is possible to do
'efficient' division with floats using shifts?
 
D

Dave Townsend

Cesar Rabak said:
Dave said:
[snipped]
Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to investigate
the benefits of using a CORDIC algorithm. I was looking for a "shift" type
operation which would divide a double by a power of two which presumably
would be more efficient than a general purpose division algorithm. If
people have some useful comments, please post.

Dave,

For start of the discourse, why in the Earth you think it is possible to do
'efficient' division with floats using shifts?
Why not? I never did computer science at school, so I only have a limited
knowledge of how floating point numbers are manipulated in the hardware.
From what I do know, it doesn't seem a stretch to shift the mantissa part of
the number by 2 and then deal with the possible change in mantissa? That
would appear to be less effort than a general double precision divide. What
am I missing here?

I thought there might be a special instruction on many CPU architectures
which could do divide by a power of two. Notice that I did put "shift" in
quotes, not to imply that it was literally possible that the operation could
be done in shifts. The idea is not so unreasonable, the CORDIC algorithm
is used extensively in chip design where the "divide-by-power-of-two" can
be performed by relatively simple digital logic. For that matter, I
understand that a lot of early portable calculators computed trig functions
this way.

Oh, dear, perhaps this is getting a little too far off-topic?
 
C

Cesar Rabak

Dave said:
Cesar Rabak said:
Dave said:
[snipped]
Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to
investigate the benefits of using a CORDIC algorithm. I was looking for
a "shift" type
operation which would divide a double by a power of two which
presumably would be more efficient than a general purpose division
algorithm. If people have some useful comments, please post.

Dave,

For start of the discourse, why in the Earth you think it is possible to do
'efficient' division with floats using shifts?
Why not? I never did computer science at school, so I only have a limited
knowledge of how floating point numbers are manipulated in the hardware.

OK. This explains certain things.
From what I do know, it doesn't seem a stretch to shift the mantissa part
of
the number by 2 and then deal with the possible change in mantissa? That
would appear to be less effort than a general double precision divide.
What am I missing here?

The first thing I think you should consider is that in most hosted
environments the floating point operation will done in a specific silicon
real state in the machine generally called "Floating Point Processor" or
something along this name.

Caveat: YMMV if you're coding for free standing environments like SBCs or
some other exotic hardware.

Second thing is the representation of the mantissa can not be in a format
that shifting bits may be not enough to do a division by two.

Last but not the least. It remains that the platform gives you access to
manipulating the mantissa bits themselves and then (obviously that would be
not portable from this point on) a means to expose this to the compiler
you're using.
I thought there might be a special instruction on many CPU architectures
which could do divide by a power of two. Notice that I did put "shift" in
quotes, not to imply that it was literally possible that the operation
could
be done in shifts.

OK. I see you put '"shift" in quotes'. I think we can now settle this
special instruction, even if it exists for some exotic architecture, is not
part of the C++ standard.

You would need to check the targed CPU of your project and then see if it is
worhtwhile to expend time to call it via an embedded assembly instruction.
is used extensively in chip design where the "divide-by-power-of-two" can
be performed by relatively simple digital logic. For that matter, I
understand that a lot of early portable calculators computed trig
functions this way.

The CORDIC algorithm and specially the trick you mention is intended for use
when all the math is done with integer arithmetic. I also was exposed to
the CORDIC routine with this information the early hand calculator used it.

HTH
 
D

Dave Townsend

Cesar Rabak said:
Dave said:
Cesar Rabak said:
Dave Townsend wrote:


[snipped]
Did everybody get out of bed on the wrong side this morning?
I'm not trashing anybody or any compiler, I'm just trying to
investigate the benefits of using a CORDIC algorithm. I was looking for
a "shift" type
operation which would divide a double by a power of two which
presumably would be more efficient than a general purpose division
algorithm. If people have some useful comments, please post.

Dave,

For start of the discourse, why in the Earth you think it is possible
to
do
'efficient' division with floats using shifts?
Why not? I never did computer science at school, so I only have a limited
knowledge of how floating point numbers are manipulated in the hardware.

OK. This explains certain things.
From what I do know, it doesn't seem a stretch to shift the mantissa part
of
the number by 2 and then deal with the possible change in mantissa? That
would appear to be less effort than a general double precision divide.
What am I missing here?

The first thing I think you should consider is that in most hosted
environments the floating point operation will done in a specific silicon
real state in the machine generally called "Floating Point Processor" or
something along this name.

Caveat: YMMV if you're coding for free standing environments like SBCs or
some other exotic hardware.

Second thing is the representation of the mantissa can not be in a format
that shifting bits may be not enough to do a division by two.

Last but not the least. It remains that the platform gives you access to
manipulating the mantissa bits themselves and then (obviously that would be
not portable from this point on) a means to expose this to the compiler
you're using.
I thought there might be a special instruction on many CPU architectures
which could do divide by a power of two. Notice that I did put "shift" in
quotes, not to imply that it was literally possible that the operation
could
be done in shifts.

OK. I see you put '"shift" in quotes'. I think we can now settle this
special instruction, even if it exists for some exotic architecture, is not
part of the C++ standard.

You would need to check the targed CPU of your project and then see if it is
worhtwhile to expend time to call it via an embedded assembly instruction.
is used extensively in chip design where the "divide-by-power-of-two" can
be performed by relatively simple digital logic. For that matter, I
understand that a lot of early portable calculators computed trig
functions this way.

The CORDIC algorithm and specially the trick you mention is intended for use
when all the math is done with integer arithmetic. I also was exposed to
the CORDIC routine with this information the early hand calculator used it.

HTH
Cesar,

Thanks that was useful information. I think I understand that I could apply
this CORDIC algorithm
if I can use integer arithmetic ( which is ok). In fact, the algorithm will
eventually run on a special
multiprocessor chip without OS and without a coprocessor, the investigation
was to look at a simulation
of the code written in C and running on a workstation to evaluate
performance, size, pros/cons, etc.

thanks,
dave
 
J

Jerry Coffin

<[email protected]>,
(e-mail address removed) says...

[ ... ]
Thanks that was useful information. I think I understand that I could apply
this CORDIC algorithm if I can use integer arithmetic ( which is ok).

You can apply CORDIC to floating point as well -- though
it works a bit differently.

Floating point is an integer with a scale factor --
nothing more or less than that. For fixed point, the
scale factor is...fixed. For floating point, you store
the scale factor along with the integer being scaled.

That means a few things are a bit different when you do
math on floating point numbers -- but only a few things.
You're dealing a number of the form 2^N * y. That means
to multiply, you have to add the exponents and multiply
the significands. To divide, you subtract exponents and
divide the significands. Interestingly, addition and
subtraction are almost more complex than multiplication
or division -- you have to normalize the two numbers so
they have the same exponent, and then add or subtract the
significands. (e.g. 1.2e12 + 1.1e10 => 1200e10 + 1.1e10
=> 1201.1e10)

When you're done with whichever operation above, you need
to re-normalize your results (if possible -- if it's not
possible, you'll have to decide whether to support
denormals or not).

If memory serves, CORDIC is mostly matrix multiplication,
which means lots of multiplication and addition but
little or no subtraction or division. I don't believe
that CORDIC in general reduces all multiplications to
powers of two though -- at least IIRC, you have to
restrict the angles you work with to get that.
In fact, the algorithm will eventually run on a special
multiprocessor chip without OS and without a coprocessor,
the investigation was to look at a simulation of the
code written in C and running on a workstation to evaluate
performance, size, pros/cons, etc.

The first thing to consider would be what your processor
supports natively, and what you need for your final
results. If you need a format (e.g. floating point) that
it doesn't support directly, you'll need emulate it on
your own to produce results that really mean much. Using
your compiler's native floating point will tell you
nearly nothing about what emulated floating point on your
target will be like. To emulate the floating point, you
could start with something along this line:

struct FP {
unsigned int exponent : 8;
long significand : 24;

FP(float const &initial);
FP const &operator=(FP const &c);
};

FP operator+(FP const &a, FP const &b);
FP operator-(FP const &a, FP const &b);
FP operator*(FP const &a, FP const &b);
FP operator/(FP const &a, FP const &b);
// quite a few more operators and probably functions
// to provide as well.

This particular format is a reasonable approximation of a
typical single-precision floating point type. Of course,
it'll be up to you to emulate it in a usable fashion. As
a lot of hardware manufacturers have found, doing
floating point at all is hard; doing it well is quite a
bit harder.

Of course, if you're going to do fixed point, the same
basic point applies -- meaningful results will depend
(heavily) upon closely emulating what you're going to do
on your target machine.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top