Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Calculate Y axis distance

Reply
Thread Tools

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
 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      05-05-2012
David RF <> 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.

 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      05-05-2012
On Sat, 5 May 2012 10:36:28 -0700 (PDT), David RF
<> 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
 
Reply With Quote
 
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
> <> 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
 
Reply With Quote
 
David RF
Guest
Posts: n/a
 
      05-06-2012
On 5 mayo, 21:51, Barry Schwarz <schwa...@dqel.com> wrote:
> On Sat, 5 May 2012 10:36:28 -0700 (PDT), David RF
>
> <davran...@gmail.com> 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
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      05-06-2012
"David RF" <> wrote in message
news:c814ba93-372c-460f-93b7-...

> 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

 
Reply With Quote
 
 
 
Reply

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 Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Javascript function to calculate distance between points sarah.kidd Javascript 2 04-14-2008 04:45 PM
can google earth calculate the shortest distance between 2 points dann Computer Support 12 07-29-2006 06:07 PM
AXIS jars org.apache.axis.wsi.* and org.apache.axis.transport.jms.* unkwb@web.de Java 0 02-23-2005 04:02 PM
calculate distance =?Utf-8?B?bWFoc2E=?= ASP .Net 1 05-13-2004 05:25 AM
axis.jar does not contain org.apache.axis.client.ServiceClient? Joey Vendetta Java 0 04-01-2004 05:51 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57