Velocity Reviews > Calculate Y axis distance

# Calculate Y axis distance

David RF
Guest
Posts: n/a

 05-05-2012
Hi folks, first of all excuse my poor english, I have build this
function for calulate Y axis distance, I wan't to know if there is a
way to increase performance or improve the algorithm (dgra is called
many many times) Thanks.

#include <stdio.h>

double ddiv(double a, double b)
{
return b == 0.0 ? 0.0 : a / b;
}

double dgra(double d, int *n)
{
const double a[] = {1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0,
7.5, 8.0, 10.0, 12.5};
const double *pa = a;
double sign, product;

if (d == 0.0) {
if (n) *n = 0;
return 0.0;
}
d *= sign = (d > 0.0) ? 1.0 : -1.0; /* Store sign */
/* Trunc to most significant (by example 15678 turns into
1.567 */
if (d < 1.0) {
for (product = 1.0; d < 1.00; product *= 0.10, d *=
10.0);
} else {
for (product = 1.0; d > 10.0; product *= 10.0, d *=
0.10);
}
d *= 1.1; /* Increase number 10% */
while (*pa < d) pa++; /* Search optimal value */
/* Must be divide by n numbers */
if (n) {
if (*pa == 1.5 || *pa == 3.0 || *pa == 6.0)
*n = 3; else
if (*pa == 2.0 || *pa == 4.0 || *pa == 8.0)
*n = 4; else
*n = 5;
}
return *pa * sign * product;
}

int main(void)
{
/* Test */
const double a[] = {112.8, -13.245, 121.5, 27894.0, 0.22452,
463.20, 7094.230, 235.20, 1420.04, 992312.52, 0.0};
const double *pa = a;
double d, f;
int n;

while (*pa) {
d = dgra(*pa, &n);
f = ddiv(d, n);
printf("%f = %f\n", *pa, d);
while (n >= 0) {
printf("\t%f\n", f * n);
n--;
}
pa++;
}
return 0;
}

--
David

Stefan Ram
Guest
Posts: n/a

 05-05-2012
David RF <(E-Mail Removed)> writes:
>I wan't to know if there is a
>way to increase performance

Yes: to measure the run-time of the application under the
target environment (of the customer) and then trying the
optimization techniques like: replacing double by float,
trying compiler-options (like -O3), using a
profiler/valgrind to analyze behavior (like cache misses,
KCacheGrind), loop unroling, cache-friendliness, inline
functions, strength reduction, reduction of register
pressure, writing in assembly, using »const«/»restrict« to
allow more optimizations.

Barry Schwarz
Guest
Posts: n/a

 05-05-2012
On Sat, 5 May 2012 10:36:28 -0700 (PDT), David RF
<(E-Mail Removed)> wrote:

>Hi folks, first of all excuse my poor english, I have build this
>function for calulate Y axis distance, I wan't to know if there is a
>way to increase performance or improve the algorithm (dgra is called
>many many times) Thanks.

In the code you show, dgra is called only 10 times. Unless this is
only an example and you actually call it several thousand times, no
improvement is likely to have a noticeable affect.

>
>#include <stdio.h>
>
>double ddiv(double a, double b)
>{
> return b == 0.0 ? 0.0 : a / b;
>}

This function is unnecessary. See comment in main.

>
>double dgra(double d, int *n)
>{
> const double a[] = {1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0,
>7.5, 8.0, 10.0, 12.5};

If you make a static, it will not get reinitialized each time you call
dgra which will save some time.

> const double *pa = a;

Suggestion: If you change pa to an int (not const) and initialize it
to 0, you can save some time at the end of dgra. To do this, also add
an integer array parallel to a
static const int b[] = {5, 3, 4, 5, 3, 4, 5, 3, 5, 4, 5,5};

> double sign, product;
>
> if (d == 0.0) {
> if (n) *n = 0;
> return 0.0;
> }
> d *= sign = (d > 0.0) ? 1.0 : -1.0; /* Store sign */

Multiplication of doubles can be time consuming. The following may be
faster.
if (d > 0.0)
sign = 1.0;
else
{
sign = -1.0;
d = -d;
}

> /* Trunc to most significant (by example 15678 turns into
>1.567 */

You should be aware that if d is 11.5, it will be represented exactly
but -

> if (d < 1.0) {
> for (product = 1.0; d < 1.00; product *= 0.10, d *=
>10.0);
> } else {
> for (product = 1.0; d > 10.0; product *= 10.0, d *=
>0.10);

after multiplying by .1, d will not equal 1.15 because that number
cannot be represented exactly.

> }
> d *= 1.1; /* Increase number 10% */
> while (*pa < d) pa++; /* Search optimal value */

Suggestion continued: All expressions in dgra of the form *pa need to
be changed to a[pa].

> /* Must be divide by n numbers */
> if (n) {
> if (*pa == 1.5 || *pa == 3.0 || *pa == 6.0)
> *n = 3; else
> if (*pa == 2.0 || *pa == 4.0 || *pa == 8.0)
> *n = 4; else
> *n = 5;
> }

Suggestion completed: This entire sequence can then be replace by
if (n)
*n = b[pa];

> return *pa * sign * product;
>}
>
>int main(void)
>{
> /* Test */
> const double a[] = {112.8, -13.245, 121.5, 27894.0, 0.22452,
>463.20, 7094.230, 235.20, 1420.04, 992312.52, 0.0};
> const double *pa = a;
> double d, f;
> int n;
>
> while (*pa) {
> d = dgra(*pa, &n);
> f = ddiv(d, n);

You could replace the call to ddiv with the same one statement that
ddiv contains, just change the variable names. This will eliminate
the overhead calling the function.
f = (n == 0.0 ? 0.0 : d/n);

> printf("%f = %f\n", *pa, d);
> while (n >= 0) {
> printf("\t%f\n", f * n);
> n--;
> }
> pa++;
> }
> return 0;
>}

--
Remove del for email

Ian Collins
Guest
Posts: n/a

 05-05-2012
On 05/ 6/12 07:51 AM, Barry Schwarz wrote:
> On Sat, 5 May 2012 10:36:28 -0700 (PDT), David RF
> <(E-Mail Removed)> wrote:
>
>> Hi folks, first of all excuse my poor english, I have build this
>> function for calulate Y axis distance, I wan't to know if there is a
>> way to increase performance or improve the algorithm (dgra is called
>> many many times) Thanks.
>>
>> #include<stdio.h>
>>
>> double ddiv(double a, double b)
>> {
>> return b == 0.0 ? 0.0 : a / b;
>> }

>
> This function is unnecessary. See comment in main.

<snip>

>> int main(void)
>> {
>> /* Test */
>> const double a[] = {112.8, -13.245, 121.5, 27894.0, 0.22452,
>> 463.20, 7094.230, 235.20, 1420.04, 992312.52, 0.0};
>> const double *pa = a;
>> double d, f;
>> int n;
>>
>> while (*pa) {
>> d = dgra(*pa,&n);
>> f = ddiv(d, n);

>
> You could replace the call to ddiv with the same one statement that
> ddiv contains, just change the variable names. This will eliminate
> the overhead calling the function.

Any compiler worth using will do that for you. All you loose by
removing the function is clarity - assuming the function name is meaningful!

--
Ian Collins

David RF
Guest
Posts: n/a

 05-06-2012
On 5 mayo, 21:51, Barry Schwarz <(E-Mail Removed)> wrote:
> On Sat, 5 May 2012 10:36:28 -0700 (PDT), David RF
>
> <(E-Mail Removed)> wrote:
> >Hi folks, first of all excuse my poor english, I have build this
> >function for calulate Y axis distance, I wan't to know if there is a
> >way to increase performance or improve the algorithm (dgra is called
> >many many times) Thanks.

>
> In the code you show, dgra is called only 10 times. *Unless this is
> only an example and you actually call it several thousand times, no
> improvement is likely to have a noticeable affect.
>
>
>
> >#include <stdio.h>

>
> >double ddiv(double a, double b)
> >{
> > * * * *return b == 0.0 ? 0.0 : a / b;
> >}

>
> This function is unnecessary. *See comment in main.
>
>
>
> >double dgra(double d, int *n)
> >{
> > * * * *const double a[] = {1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0,
> >7.5, 8.0, 10.0, 12.5};

>
> If you make a static, it will not get reinitialized each time you call
> dgra which will save some time.
>
> > * * * *const double *pa = a;

>
> Suggestion: If you change pa to an int (not const) and initialize it
> to 0, you can save some time at the end of dgra. *To do this, also add
> an integer array parallel to a
> * * static const int b[] = {5, 3, 4, 5, 3, 4, 5, 3, 5, 4, 5,5};
>
> > * * * *double sign, product;

>
> > * * * *if (d == 0.0) {
> > * * * * * * * *if (n) *n = 0;
> > * * * * * * * *return 0.0;
> > * * * *}
> > * * * *d *= sign = (d > 0.0) ? 1.0 : -1.0; /* Store sign */

>
> Multiplication of doubles can be time consuming. *The following may be
> faster.
> * * *if (d > 0.0)
> * * * * * sign = 1.0;
> * * *else
> * * * * * {
> * * * * * sign = -1.0;
> * * * * * d = -d;
> * * * * * }
>
> > * * * */* Trunc to most significant (by example 15678 turns into
> >1.567 */

>
> You should be aware that if d is 11.5, it will be represented exactly
> but -
>
> > * * * *if (d < 1.0) {
> > * * * * * * * *for (product = 1.0; d < 1.00; product *= 0.10, d *=
> >10.0);
> > * * * *} else {
> > * * * * * * * *for (product = 1.0; d > 10.0; product *= 10.0, d *=
> >0.10);

>
> after multiplying by .1, d will not equal 1.15 because that number
> cannot be represented exactly.
>
> > * * * *}
> > * * * *d *= 1.1; /* Increase number 10% */
> > * * * *while (*pa < d) pa++; /* Search optimal value */

>
> Suggestion continued: All expressions in dgra of the form *pa need to
> be changed to a[pa].
>
> > * * * */* Must be divide by n numbers */
> > * * * *if (n) {
> > * * * * * * * *if (*pa == 1.5 || *pa == 3.0 || *pa == 6.0)
> > * * * * * * * * * * * **n = 3; else
> > * * * * * * * *if (*pa == 2.0 || *pa == 4.0 || *pa == 8.0)
> > * * * * * * * * * * * **n = 4; else
> > * * * * * * * * * * * **n = 5;
> > * * * *}

>
> Suggestion completed: This entire sequence can then be replace by
> * * *if (n)
> * * * * **n = b[pa];
>
> > * * * *return *pa * sign * product;
> >}

>
> >int main(void)
> >{
> > * * * */* Test */
> > * * * *const double a[] = {112.8, -13.245, 121.5, 27894.0, 0.22452,
> >463.20, 7094.230, 235.20, 1420.04, 992312.52, 0.0};
> > * * * *const double *pa = a;
> > * * * *double d, f;
> > * * * *int n;

>
> > * * * *while (*pa) {
> > * * * * * * * *d = dgra(*pa, &n);
> > * * * * * * * *f = ddiv(d, n);

>
> You could replace the call to ddiv with the same one statement that
> ddiv contains, just change the variable names. *This will eliminate
> the overhead calling the function.
> * * * * * * * *f = (n == 0.0 ? 0.0 : d/n);
>
> > * * * * * * * *printf("%f = %f\n", *pa, d);
> > * * * * * * * *while (n >= 0) {
> > * * * * * * * * * * * *printf("\t%f\n", f * n);
> > * * * * * * * * * * * *n--;
> > * * * * * * * *}
> > * * * * * * * *pa++;
> > * * * *}
> > * * * *return 0;
> >}

>

Thanks Barry

BartC
Guest
Posts: n/a

 05-06-2012
"David RF" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...

> const double a[] = {1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0,
> 7.5, 8.0, 10.0, 12.5};

> if (*pa == 1.5 || *pa == 3.0 || *pa == 6.0)
> *n = 3; else
> if (*pa == 2.0 || *pa == 4.0 || *pa == 8.0)
> *n = 4; else
> *n = 5;

pa always points into the a[] array, and the contents of a[] are fixed? Then
it might be better to use an index into the array, and use tests such as:

if (index==1 || index==4 || index==6)

etc.

> while (*pa) {
> d = dgra(*pa, &n);
> f = ddiv(d, n);
> printf("%f = %f\n", *pa, d);
> while (n >= 0) {
> printf("\t%f\n", f * n);
> n--;
> }
> pa++;
> }

Comment out the printf() statements, wrap a loop around it to execute it at
least a million times (remember to re-initialise pa each time), and find
some way of timing the code. Then it will be easy to try different things
and see if they make a difference. Reinstate the printf() statements every
so often (and disable the outer loop) to check the output is still right.

--
Bartc

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post sarah.kidd Javascript 2 04-14-2008 04:45 PM dann Computer Support 12 07-29-2006 06:07 PM unkwb@web.de Java 0 02-23-2005 04:02 PM =?Utf-8?B?bWFoc2E=?= ASP .Net 1 05-13-2004 05:25 AM Joey Vendetta Java 0 04-01-2004 05:51 PM

Advertisments