The hardcoded prime list (lista_primi) serves as the bootstrap for marking
composites in segment 0. This list must contain all primes up to the
square root of the segment 0 upper bound:
radice_0 = sqrt(dimensione_maschera × 60) + 1
If the bootstrap list is too short, composites whose smallest prime factor lies above the list's last entry will not be marked in segment 0 causing a silent overcounting of primes.
If you change dimensione_maschera, update the bootstrap list accordingly:
dimensione_maschera |
radice_0 |
Bootstrap must reach |
|---|---|---|
| 65.536 | 1.983 | 1.979 (296 primes) |
| 131.072 | 2.805 | 2.803 (406 primes — current) |
| 262.144 | 3.966 | 3.947 (545 primes) |
| 524.288 | 5.609 | 5.591 (735 primes) |
| 1.048.576 | 7.932 | 7.927 (998 primes) |
The bootstrap list can be generated with any prime sieve or verified with
sympy.isprime. The formula is deterministic no guesswork required.
The Passive Container Segmented Sieve GC-60 project was conceived as a perspective differentiated from traditional sieves, with the intent of leveraging resource efficiency, data independence, and structural stability.
The four fundamental differences are described below, formalized mathematically where relevant.
The primary difference does not lie in the modulus
The wheel is centered at the origin
Where
The periodicity is mathematically sound but abstract with respect to the decimal system.
The structure is anchored at
Where
Significance: The translation
The way composite numbers are identified defines the philosophy of the algorithm.
The algorithm actively propagates divisibility information. For each prime
-
Logic: "For each prime
$p$ , find its multiples and cross them off." -
State: Segments are coupled; the position of the next multiple is propagated from segment
$i$ to segment$i+1$ .
The algorithm treats the segment as a passive structure that receives exclusion patterns. Elimination occurs through internal composition within the structured domain
- Logic: "I have a fixed structure (the container). I apply logical masks to determine which positions are hit by the divisors."
-
State: Radical Independence. Each segment
$S_i$ is computed as:
Without depending on the final state of ricerca_ciclo(p, riferimento) is recomputed for each segment, trading CPU time for logical isolation.
To save CPU cycles, classical segmented sieves globally store the propagation state for each sieving prime up to
-
Memory cost:
$O(\pi(\sqrt{N}))$ for the prime list +$O(\pi(\sqrt{N}))$ for the global state (offsets/maps). -
Limitation: For
$\sqrt{N} \approx 3\ \text{billion}$ , the RAM required to store maps or complex states for each prime can become prohibitive (tens or hundreds of GB).
The cycle map (ricerca_ciclo) is recomputed for each segment, eliminating the need to store any global propagation state.
-
Memory cost:
$O(\pi(\sqrt{N}))$ for the prime list +$O(1)$ for the segmentation state (local buffer). -
Advantage: The operational memory per segment is constant and independent of
$N$ . With no global maps to maintain in RAM, the bottleneck shifts from memory capacity to computing power. - In practice:
Independent of the complexity of the divisor maps.
Both approaches must store the sieving prime list ($O(\pi(\sqrt{N}))$), but GC-60 eliminates the additional overhead tied to preserving propagation state (global maps/offsets), allowing operation at theoretical scales (
The system compresses 60 natural numbers into a 16-bit word (uint16_t). The information density
| Method | Bits per number |
|---|---|
| Classical bit-sieve | 1 bit |
| GC-60 | ~0.266 bit |
| Density gain | ~3.75× |
The elimination operation is an atomic logical instruction on the CPU:
This allows processing 16 candidates simultaneously at processor clock speed.
| Feature | Industrial Sieves (e.g. primesieve) | GC-60 Sieve Wheel |
|---|---|---|
| Primary Goal | Speed (Throughput) | Memory Efficiency and Logic |
| Generator Equation | ||
| Segment Management | Propagated state (Coupled) | Recomputed state (Independent) |
| RAM Complexity |
|
|
| Philosophy | Active hunt for multiples | Interrogation of passive containers |
| Output | Immediate result | Persistent and regenerable archive |
The passive container model is not limited to counting primes from 2 to N.
Because each GC-60 segment is structurally independent — it does not require the propagated state of any previous segment, the sieve can be aimed at an arbitrary window [A, A + L] positioned anywhere on the number line, including far beyond the 64-bit limit of ~1.8 × 10¹⁹.
The window_exploration folder documents this extension:
- Targets verified from 10²¹ to 10²⁷ with a fixed window of 10,000,000
- Phase 1 scales linearly with the number of GC-60 cycles (~×10 per order of magnitude)
- Phase 2 (passive window sieve) runs in ~0.3 seconds regardless of target magnitude
- All results verified against the
nextprimesequence — no errors detected - No upper bound has been encountered;
__int128supports targets to ~3.4 × 10³⁸
primesieve and similar tools are limited to values below ~1.8 × 10¹⁹. All runs in the window exploration table exceed that limit.
→ See window_exploration/README.md
This project started as a computational experiment on prime number distribution, with an initial Python prototype to validate the core idea. The evolution followed three stages:
- Python — conceptual prototype, logic validation
- sieve_wheel_M60_7 — first performant C++ implementation, used as reference benchmark
- V3.0.0 — optimized rewrite in C++ and Julia, with AI-assisted low-level optimization (Claude and Gemini)
The use of AI tools is stated transparently: the algorithmic intuitions and architectural decisions remain the author's, while AI accelerated the implementation of critical low-level optimizations.
The defining characteristic of this sieve is what it does not do.
In a classical sieve, the algorithm actively interrogates each candidate: "is this number a multiple of p?"
In this implementation, the segment is a passive container — it receives exclusion patterns without ever being interrogated. For each sieving prime p, the algorithm pre-computes a fixed pattern of 16 residues (the mod-60 multiples of p) and blindly translates that pattern onto the segment. No individual candidate is ever checked. The container simply accumulates marks from all primes, and what remains unmarked at the end is prime.
Concrete example with p = 7:
All numbers follow the form
| Range | Cycles | Primes to √n | Total primes | Time |
|---|---|---|---|---|
| 10,003,415,040 | 1,272 | 9,590 | 455,200,781 | 1.12 s |
| 100,057,743,360 | 12,723 | 27,297 | 4,120,334,844 | 12.51 s |
| 1,000,616,755,200 | 127,235 | 78,520 | 37,630,234,099 | 177.75 s |
| Range | Cycles | Primes to √n | Total primes | Time |
|---|---|---|---|---|
| 10,003,415,041 | 1,272 | 9,590 | 455,200,781 | 7.63 s |
| 100,057,743,349 | 12,723 | 27,297 | 4,120,334,844 | 115.28 s |
| 1,000 billion | 127,235 | — | — | aborted |
The 1 trillion test in Julia was aborted — execution time was out of scale compared to C++. Julia's scaling degrades significantly at very large ranges with 8 threads, likely due to memory management and JIT overhead on data structures of this size.
10 billion → 1.12 s
100 billion → 12.51 s (11.2× — near linear)
1 trillion → 177.75 s (14.2× — expected degradation)
The degradation at 1 trillion is explained by the growth of the sieving prime list:
Each segment performs approximately
| Implementation | Time | Memory (sieving primes) |
|---|---|---|
| sieve_wheel_M60_7 | 456.5 s | ~37 billion elements in RAM |
| V3.0.0 C++ | 177.8 s | ~78,000 elements in RAM |
| Speedup | 2.6× | ~500,000× |
Structural difference:
- M60_7 — parallelizes over primes within each segment (shared mask contention)
- V3.0.0 — assigns full independent segments to each thread (private mask, zero contention)
Recommended: Visual Studio, Console project, Release x64.
Enable the following compiler options:
- OpenMP support (
/openmp) - AVX2 instruction set (
/arch:AVX2) - C++20 standard (required for
std::popcountand<bit>)
julia --threads=8 sieve_wheel_M60.jlThis is an experimental project with a solid and verified base. Contributions are welcome, particularly around:
- Further parallelization strategies
- Memory layout optimizations
- Validation against independent prime counting references
- Port to other languages (Rust, Go)
Open an issue on GitHub if you are interested in collaborating.
The GC-60 Sieve Wheel project does not position itself as a replacement for optimized industrial libraries such as primesieve, nor does it aim to compete on raw execution speed. Classical algorithms benefit from decades of low-level optimizations (assembly, prefetching, vectorization) carried out by expert teams on specific hardware.
The goal of this work is different: to demonstrate that the Passive Container concept represents a valid starting point for rethinking the interpretation of the traditional wheel.
While classical sieves treat the data structure as an active buffer to fill and propagate, the GC-60 Sieve Wheel proposes a static view:
- The structure (the container) exists independently of the computation.
- Divisibility information is projected onto the structure via logical masks.
- Primality emerges as a residual state — what is not marked — rather than as the active result of a search.
This divergence does not make the algorithm "better" in terms of throughput, but makes it conceptually alternative. It offers a search logic where segment independence and constant memory occupancy take priority over minimizing clock time.
The practical value of this approach lies in its sustainability under different resource constraints:
This characteristic allows operation at theoretical scales (
The GC-60 Sieve Wheel does not seek to break speed records, but to expand the solution space:
- For theoretical research, it offers a model where structural periodicity (translation +10) can be studied as a fixed environment.
- For software engineering, it demonstrates that persistent, independent archives can be built without relying on global computation state.
The project is therefore proposed as a complementary tool in the ecosystem of computational number theory: not to replace existing tools, but to accompany them by offering a passive container logic that makes the structure of prime numbers readable through a different lens — one where efficiency is measured in architectural stability and resource savings, as well as in speed.