Karim BELABAS on Mon, 10 Jun 2002 00:52:43 +0200 (MEST)


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

30- library API


On Sun, 9 Jun 2002, Karim BELABAS wrote:
>    30- INCOMPATIBILITY: [library] polred & polredabs do not take a 'prec'
>    37- INCOMPATIBILITY: removed gentimer() / genmsgtimer(). Use TIMER/msgTIMER

30- is straightforward: the 'prec' parameter of polred* functions was unused
(the routine now determine an adequate floating point accuracy for the LLL
reduction). So I removed it. C programs have to be updated.

37- is more annoying. I had introduced the gen*timer() routines to get finer
timings than would be available using only the built-in timer() / timer2()
functions. Also PARI timers work in a slightly weird way: they return the
delay since the last time they were called, if some other routine uses the
timer when you're not looking, you get junk.

So it worked like this: you had to reserve a unique "timer identifier" from
get_timer(), and give it as argument to the gen*timer() routines to specify
which timer they should use. Then you had to "release" the identifier, so
that it can be re-used  [ there was a hardcoded limit of 32 simultaneous
timers ]

It was documented but rather obscure and, as far as I know, nobody used it
correctly (even the PARI code had it wrong, using the identifiers without
reserving them first).

I came up with the following alternative: we have a private struct

  struct pari_timer {
    long s;   /* number of seconds */
    long us;  /* number of microseconds */
  }
(= struct timeval from <sys/time.h>)

to store information about time . And a routine to fill and exploit it:

  long TIMER(struct pari_timer *T)        [ msgTIMER is similar ]

  return the delay since


It works like this

  fun()
  {
    pari_timer T;
    long t;

    (void)TIMER(&T); /* initialize timer */
    ...
    t = TIMER(&T);   /* number of ms since last call to timer T */
  }

The members of T never need to be accessed directly, they simply translate in
a uniform way the output from the various time routine we might be using:
getrusage(), ftime(), GetTickCount(), clock() etc.

Probably the

  (void)TIMER(&T);

could be replaced by something like

  initTIMER(&T);

The names are debatable, but I think it's neater than the "identifier"
approach, and easier to use.


Problems:
1) I'd rather not leave the functions using the old interface (gentimer /
genmsgtimer) around, because they are ugly and a bit dangerous. Also they've
been introduced comparatively recently (2.0.18, december 1999) and I believe
nobody uses them. But there is a theoretical risk that programs would be
broken.

2) I could not test the new timers for all the time routines they are
supposed to encapsulate: I checked times(), getrusage(), ftime() and clock().
GetTickCount (#define WINCE), TickCount (#define macintosh) anyone ?

    Karim.
-- 
Karim Belabas                    Tel: (+33) (0)1 69 15 57 48
Dép. de Mathematiques, Bat. 425  Fax: (+33) (0)1 69 15 60 19
Université Paris-Sud             Email: Karim.Belabas@math.u-psud.fr
F-91405 Orsay (France)           http://www.math.u-psud.fr/~belabas
--
PARI/GP Home Page: http://www.parigp-home.de/