Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: Question on performance



       John,

> As far as I can see in your example code, t never is NaN throughout the loop. Wouldn't it be useful to have tests where the other branch of "isnan (x) ? 0.0 : x" is taken (a) in a regular pattern, (b) in a random way? That would test, for instance, what effect the hardware's branch-prediction has on performance.

with a regular pattern, I get the following (note the 2nd run performs more
work):

tarte% gcc -DTEST -O2 -g neumaier.c -lm
tarte% time ./a.out
GNU libc version: 2.11.2
GNU libc release: stable
s=2.7182818284590455e+00
2.237u 0.000s 0:02.25 99.1%     0+0k 0+0io 0pf+0w

tarte% gcc -DTEST -DWITHNAN -O2 -g neumaier.c -lm
tarte% time ./a.out
GNU libc version: 2.11.2
GNU libc release: stable
s=2.7182818284590455e+00
3.550u 0.000s 0:03.56 99.7%     0+0k 0+0io 0pf+0w

Paul

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gnu/libc-version.h>

#ifdef LIBC
#define ISNAN isnan
#else
#define ISNAN(x) ((x) != (x))
#endif

#ifdef INLINE
#define nan2zero(x) ((ISNAN(x))?0.0:x)
#else
double
nan2zero (double x)
{
  return ISNAN(x) ? 0.0 : x;
}
#endif

int
main()
{
  double t, u, s, i, N = 1000000000.0;
  
  printf("GNU libc version: %s\n", gnu_get_libc_version ());
  printf("GNU libc release: %s\n", gnu_get_libc_release ());

  /* compute s = sum(1/k!, k=0..N) */
  for (t = 1.0, u = 0.0 / 0.0, s = t, i = 1; i <= N; i++)
    {
      t /= i;
#ifdef TEST
      s += nan2zero (t);
#else      
      s += t;
#endif

#ifdef WITHNAN
      u /= i;
      s += nan2zero (u);
#endif
    }
  printf ("s=%.16e\n", s);
}