La petite séquence ASM permet de comprendre que la p-factorielle 5 (qui est égale à 2*3*5) est la seule p-factorielle à s'adapter à l'architecture 64 bits : son cycle de 8 nombres susceptibles d'être premier tient dans un seul registre. Pour que la p-factorielle 7 soit envisageable, il faut attendre l'optimisation matérielle de l'instruction machine LZCNT.
Code : Tout sélectionner
#P2 = 25 ; on passe de 2^24 à 2^25 pour garder notre durée...
#sMax = 1 << (#P2 - 3) - 1
Macro sGet(K0, M0)
((s(K0) >> M0) & 1)
EndMacro
Macro sSet(K0, M0)
s(K0) | (1 << M0)
EndMacro
Define.I i, modu ; <--- les minuscules sont importantes en ASM
Define.I sqrMax = Sqr((#sMax + 1) * 30)
Dim s.a(#sMax) ; le crible...
s(0) = 1 ; réglage du 1 comme composite...
Dim M.I(7) ; ce tableau ne sera plus nécessaire...
M(0) = 1 ; cette liste non plus...
M(1) = 7
M(2) = 11
M(3) = 13
M(4) = 17
M(5) = 19
M(6) = 23
M(7) = 29
Dim gap.I(7)
gap(0) = 6
gap(1) = 4
gap(2) = 2
gap(3) = 4
gap(4) = 2
gap(5) = 4
gap(6) = 6
gap(7) = 2
K = 0
i0 = 1
t0 = ElapsedMilliseconds()
Repeat
K30 = 30 * K
N = K30 + M(i0)
If sGet(K, i0) = 0
N2 = N * N
If N2 >= (#sMax + 1) * 30
Break
EndIf
i1 = i0
Repeat
K_30 = N2 / 30
modu = N2 % 30
! mov rcx, [v_modu]
! mov rax, $1C0181500C804000 ; <--- la liste est compactée ici
! shl rcx, 1
! shr rax, cl
! and rax, 7
! mov [v_i], rax
sSet(K_30, I)
N2 + N * gap(i1)
i1 + 1
i1 & 7
Until N2 >= (#sMax + 1) * 30
EndIf
i0 + 1
If i0 > 7
i0 = 0
K + 1
EndIf
Until N > sqrMax
t1 = ElapsedMilliseconds()
Delay(1)
For I = 0 to #sMax
For J = 0 To 7
If s(I) >> J & 1 = 0
P + 1
EndIf
Next
Next
; On affiche quantités et durée de notre algo
MessageRequester(Str((#sMax + 1) * 30) + " nb testés", Str(t1 - t0) + " ms" + Chr(10) + Str(P) + " nbs 1ers")