Skip to content

Build a smaller hash table for n_is_prime #2504

@fredrik-johansson

Description

@fredrik-johansson

Here is the code I used to generate the list of bases for the hash table in n_is_prime: https://gist.github.com/fredrik-johansson/2c568b0b20675a22d77f89b9abdf3215

One can get the necessary list of strong base-2 pseudoprimes up to $2^{64}$ from https://flintlib.org/data/psp2.txt.xz (warning: 186 MB compressed)

Generating the hash table for n = 131072 buckets was reasonably quick, a few hours on my 8-core machine IIRC.

With some patience, one could build a table with smaller n. For example, n = 98304 = 3 * 2^15 looks feasible. Running this for 8 hours on 8 cores completes about 10% of the buckets:

...

max: 399,  average: 324
bucket 5 / 98304 : 21450  (max 21450 for 294 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
bucket 6 / 98304 : 308318  (max 308318 for 295 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1])
bucket 14 / 98304 : 82434  (max 308318 for 295 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1])
...
bucket 8052 / 98304 : 12720971  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 61, 122, 206, 454, 760, 1033, 1239, 1290, 1133, 867, 483, 239, 91, 36, 11, 4, 1])
bucket 9522 / 98304 : 370031  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 61, 122, 206, 454, 760, 1034, 1239, 1290, 1133, 867, 483, 239, 91, 36, 11, 4, 1])
bucket 9530 / 98304 : 14197  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 760, 1034, 1239, 1290, 1133, 867, 483, 239, 91, 36, 11, 4, 1])
bucket 9538 / 98304 : 182283  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 761, 1034, 1239, 1290, 1133, 867, 483, 239, 91, 36, 11, 4, 1])
bucket 9546 / 98304 : 593103  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 761, 1034, 1240, 1290, 1133, 867, 483, 239, 91, 36, 11, 4, 1])
bucket 7889 / 98304 : 27939486  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 761, 1034, 1240, 1290, 1133, 867, 483, 240, 91, 36, 11, 4, 1])
bucket 7897 / 98304 : 136819  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 762, 1034, 1240, 1290, 1133, 867, 483, 240, 91, 36, 11, 4, 1])
bucket 7912 / 98304 : 2645123  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 762, 1034, 1240, 1290, 1134, 867, 483, 240, 91, 36, 11, 4, 1])
bucket 7905 / 98304 : 548314  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 762, 1034, 1241, 1290, 1134, 867, 483, 240, 91, 36, 11, 4, 1])
bucket 7913 / 98304 : 507402  (max 736820777 for 372 histogram [0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 5, 11, 18, 42, 62, 122, 206, 454, 762, 1035, 1241, 1290, 1134, 867, 483, 240, 91, 36, 11, 4, 1])

From the histogram one sees that about 95% of the bases fit in 24 bits, so this table could presumably be stored in roughly 98304 * 24 bits ~= 288 KB. If anyone is interested in finishing this computation, it should take a few days on a multicore machine.

One drawback of choosing a non-power-of-two number of buckets is that the hash function is slightly slower to compute, but probably this tradeoff is acceptable.

The table could presumably be optimized a tiny bit by tweaking the hash function to reduce the number of outliers.

Could one reach even smaller n? 2^16 would be a nice target. After 20 core-hours, four buckets complete on my machine:

max: 579,  average: 486
bucket 3 / 65536 : 402547707  (max 402547707 for 478 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1])
bucket 2 / 65536 : 442735750  (max 442735750 for 435 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2])
bucket 10 / 65536 : 392401781  (max 442735750 for 435 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3])
bucket 18 / 65536 : 111066745  (max 442735750 for 435 histogram [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3])

Ideally most bases will fit in 32 bits in which case this table would fit nicely in 256 KB, though I'm not yet sure if this will actually be the case. It looks like this will take several core-years to complete, which could the target of a distributed computing project.

Question: is there some way to speed up this search substantially? One idea is to run the probable prime test for a SIMD vector of several bases simultaneously. There should also be no problem doing this search on a GPU (you need 64-bit integers, but even slow 64-bit integers would be fine with massive parallelism). Are there some pruning, multipoint evaluation or meet-in-the-middle tricks one could use here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions