mpz_prevprime

Seth Troisi braintwo at gmail.com
Tue Mar 10 00:15:09 UTC 2020


On Mon, Mar 9, 2020 at 5:03 AM Marco Bodrato <bodrato at mail.dm.unipi.it>
wrote:

> Ciao,
>
> Il 2020-03-09 11:59 Seth Troisi ha scritto:
> > On Mon, Mar 9, 2020 at 2:05 AM Marco Bodrato
> > <bodrato at mail.dm.unipi.it> wrote:
> >
> >> Ciao,
> >>
> >> Il 2020-03-09 02:56 Seth Troisi ha scritto:
>
> > It's highly possible I misunderstand how these macros are supposed to
> > be used.
> > I also dislike the boiler plate of the macros but I didn't like
>
> When I say "that code is messy", I mean my code.
> And you agree :-) those macros are just easy to misunderstand :-/
>
> > If you have suggestions or code pointers for a better pattern I'd
> > appreciate that.
>
> >> Did you try to use the gmp_primesieve function directly?
> >
> > I'm not sure what you're referencing here, I tried with
>
> I'm proposing to get rid of primegap, and use something like the
> following.
> This is just a copy-paste from your code, not a really working sequence!
>
> +      __sieve = TMP_ALLOC_LIMBS (primesieve_size (sieve_limit));
> +      prime_limit_pre = gmp_primesieve(__sieve, sieve_limit);
>
> +  next_mult = TMP_ALLOC_TYPE (prime_limit, unsigned int);
> [...]
> +  /* Invert p for modulo */
> +  mpz_neg(p, p);
>
> [..handle 3 outside the loop]
>
> +    LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), n_to_bit (sieve_limit),
> 0, __sieve);
> +      m = mpz_fdiv_ui(p, prime);
> +      /* Only care about odd multiplies (even indexes) */
> +      if (m & 1)
> +        m += prime;
> +
> +      /* mark off any composites in sieve */
> +      for (; m < INCR_LIMIT; m += 2*prime)
> +        sieve[m] = 1;
> +      next_mult[i] = m;
> +    LOOP_ON_SIEVE_END;
> +  mpz_neg(p, p);
>
> [...]
>
> +      /* Sieve next segment */
> [..handle 3]
> +      memset(sieve, 0, INCR_LIMIT);
> +      LOOP_ON_SIEVE_BEGIN (prime, n_to_bit (5), n_to_bit (sieve_limit),
> 0, __sieve);
> +          m = next_mult[i] - INCR_LIMIT;
> +          for (; m < INCR_LIMIT; m += prime * 2)
> +            sieve[m] = 1;
> +          next_mult[i] = m;
> +      LOOP_ON_SIEVE_END;
>
When nbits is small (IMHO the most common case) we'd like to be able to
fallback to a constant array which I don't think exist for primesieve
(because gmp_limb_bits isn't constant).
So I lowered the threshold to 150M (50MB) in the future I have a trick that
will reduce memory usage and we can try to increase this limit.


> > Is there a way to unalloc a TMP_ALLOC_LIMBS before TMP_FREE?
>
> No, if you want to unalloc, you must use __GMP_ALLOCATE_FUNC_TYPE,
> __GMP_REALLOCATE_FUNC_TYPE, and __GMP_FREE_FUNC_TYPE.
>
> > Sieve next segment is rare, the average gap is ln(n), if INCR_LIMIT
> > was changed to be a variable it could be set
> > so /*sieve next segment*/ happened on average less than once, and then
>
> Why not using a variable for INCR_LIMIT?
>
It will be another change with more moving parts. I'm hoping to do it after
the large part of this change goes in.

>
> >> In the array char *sieve, you use only the even entries. Maybe you
> >> can reduce its size by half, and remove some "*2" around the code?
> >
> > it's only 4000 entries so I wasn't bothering at this time, but it
>
> I agree.
>
Fixed now.

>
> PS: did you consider mpz_Cdiv_ui, instead of _neg,_Fdiv_ui,_neg ?
>
Nope, this is much cleaner. Thanks.

>
> Ĝis,
> m
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: nextprime_sieve_marco.patch
Type: text/x-patch
Size: 8691 bytes
Desc: not available
URL: <https://gmplib.org/list-archives/gmp-devel/attachments/20200309/bea30c2e/attachment.bin>


More information about the gmp-devel mailing list