Jens Schmidt on Tue, 04 Jul 2017 07:46:54 +0200


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

gcopy_avma() is wasting stack memory compared to gcopy()


Hello PARI developer.

PARI Library Guide (PDF) writes: "GEN gcopy_avma(GEN x, pari_sp *AVMA)
return a copy of x as from gcopy, except that we pretend that initially
avma is *AVMA, and that *AVMA is updated accordingly (so that the total
size of x is the difference between the two successive values of *AVMA)."

I noticed that gcopy_avma() needs more memory (~ 20%-30%) than gcopy()
to create a copy of a GEN object if GEN is of non recursive type, e.g.
t_POL or t_SER. Therefore I've written a shot test function to dissect
the PARI stack.

----
GEN stacktest(GEN x)
{
  pari_sp av0 = avma;           /* save stack pointer */

  pari_printf("avma=%p\n", avma);

  gcopy(x);                     /* make copy of x with gcopy() */

  pari_printf("avma=%p,      gcopy size=%ld\n", avma, av0 - avma);

  pari_sp av1 = avma;           /* save intermediate stack pointer */

  gcopy_avma(x, &avma);         /* make copy of x with gcopy_avma() */

  pari_printf("avma=%p, gcopy_avma size=%ld\n", avma, av1 - avma);

  pari_puts("\nstack contents:\n");

  dbg_gerepile(av0);   /* display stack contents between av0 and avma */

  avma = av0;           /* garbage collection */

  return gen_0;          /* return 0 */
}
----


Checking numbers like Pi or 1/7 shows no difference:

----

gp > stacktest(Pi)
avma=0x7f739f135f08
avma=0x7f739f135ee8,      gcopy size=32
avma=0x7f739f135ec8, gcopy_avma size=32

stack contents:
 [0] 3.1415926535897932384626433832795028842:
 [4] 3.1415926535897932384626433832795028842:
----

gp > stacktest(1/7)
avma=0x7f739f135eb8
avma=0x7f739f135e70,      gcopy size=72
avma=0x7f739f135e28, gcopy_avma size=72

stack contents:
 [0] 7:
 [3] 1:
 [6] 1/7:  1 [3],  7 [0]
 [9] 7:
 [12] 1:
 [15] 1/7:  1 [12],  7 [9]
----

But when using empty variables in expressions like 'a' or 'sin(x)' there
is a big difference:

----

gp > stacktest(a)
avma=0x7f739f135f38
avma=0x7f739f135f00,      gcopy size=56
avma=0x7f739f135eb8, gcopy_avma size=72

stack contents:
 [0] 1:
 [3] 0:
 [5] a:  0 [3],  1 [0]
 [9] 1:
 [12] a:  gen_0,  1 [9]
----

There is a differene in size: 56 vs. 72 bytes = 16 bytes.

Testing sin(x) yields a difference of 672 vs. 800 byte = 128 bytes


LG - Jens