Le tamis D'Atkin

j'ai essayé d'apprendre des algorithmes pour générer des nombres premiers et j'ai rencontré tamis D'Atkin sur Wikipedia. Je comprends presque toutes les parties de l'algorithme, sauf quelques-unes. Voici les questions:

  1. comment se forment les trois équations quadratiques ci-dessous? 4x^2+y^2, 3x^2+y^2 et 3x^2-y2
  2. l'algorithme DANS wikipedia parle de modulo soixante mais je ne comprends pas comment/où cela est utilisé dans le psudocode ci-dessous.
  3. comment trouve-t-on ces rappels 1,5,7 et 11?

ci-dessous est le pseudo de Wikipedia pour référence:

// arbitrary search limit                                                   
limit ← 1000000                                                             

// initialize the sieve                                                     
for i in [5, limit]: is_prime(i) ← false                                    

// put in candidate primes:                                                 
// integers which have an odd number of                                     
// representations by certain quadratic forms                               
for (x, y) in [1, √limit] × [1, √limit]:                                    
    n ← 4x²+y²                                                              
    if (n ≤ limit) and (n mod 12 = 1 or n mod 12 = 5):                      
        is_prime(n) ← ¬is_prime(n)                                          
    n ← 3x²+y²                                                              
    if (n ≤ limit) and (n mod 12 = 7):                                      
        is_prime(n) ← ¬is_prime(n)                                          
    n ← 3x²-y²                                                              
    if (x > y) and (n ≤ limit) and (n mod 12 = 11):                         
        is_prime(n) ← ¬is_prime(n)                                          

// eliminate composites by sieving                                          
for n in [5, √limit]:                                                       
    if is_prime(n):                                                         
        // n is prime, omit multiples of its square; this is                
        // sufficient because composites which managed to get               
        // on the list cannot be square-free                                
        is_prime(k) ← false, k ∈ {n², 2n², 3n², ..., limit}                 

print 2, 3                                                                  
for n in [5, limit]:                                                        
    if is_prime(n): print n  
15
demandé sur Will Ness 2013-10-15 22:08:32

2 réponses

le tamis du pseudo-code Atkin de L'article de Wikipedia que vous avez cité contient les réponses à vos questions ou la discussion sur l'article pour lequel will Ness a fourni un lien ne, Bien que vous ne pouvez pas être en mesure de mettre l'information ensemble. Les réponses courtes sont les suivantes:

  1. les trois équations proviennent de la preuve mathématique D'Atkin que tout les nombres premiers se produiront comme les solutions d'un ou plusieurs des ces trois équations avec les conditions modulo appropriées pour toutes les conditions valides les valeurs des variables " x " et "y", et en fait il a en outre prouvé que les vrais nombres premiers seront les numéros qui ont un nombre impair de les solutions à ces trois équations nombre de fois à partir des conditions initiales de False) avec le modulo conditions pour chacun, à l'exclusion des nombres divisibles par des carrés de nombres premiers inférieur ou égal à la racine carrée de la testé nombre.

  2. le vrai tamis D'Atkin est basé sur un ensemble de modulo 60 conditions; ce pseudo-code représente une simplification où il y a moins de fourchettes de conditions pour chaque équation utilisant un ensemble de modulo 12 conditions (5 × 12 = 60) - cependant, il en résulte qu'il y a 20% le travail supplémentaire effectué en raison de l'introduction de redondance dans ce nouveau ensemble de conditions. C'est aussi la raison pour laquelle cette simplifié le pseudo-code doit commencer son premier scan à 5 plutôt que de la normal 7 et pour faire les nombres premiers de base carrés éliminations libres à partir d'une prime de base de 5 à un coût supplémentaire en temps d'exécution comme les facteurs de 5 ne sont pas par ailleurs manipulés correctement. Raison pour cette simplification est peut-être de sacrifier un peu de code supplémentaire overhead afin de faciliter la complexité du code à vérifier valeurs, bien que cela puisse être fait avec une seule recherche de table alors que le supplément de plus de 30% dans le travail en raison de l'utilisation de modulo 12 ne peut pas être réduite.

  3. les "rappels" (devraient être épelés restants ) sont trouvés par le les opérateurs 'mod' dans le pseudo code que vous avez cité qui représentent le modulo opérateur, quel que soit le langage informatique utilisé, souvent représenté par le symbole " % " dans les langages informatiques tels que C, Java, C#, F#, et cetera. Cet opérateur donne l'entier reste après une division entière du dividende (le premier des nombres, avant le "mod") par le diviseur (le second des nombres, après le mod' symbole). La raison pour laquelle les restes ne sont que quatre plutôt que le 16 comme utilisé dans l'algorithme complet modulo 60 est due à les simplifications de réduire à un modulo 12 de l'algorithme. Vous remarquerez que les conditions modulo 12, la condition" 4x " passe 25 qui seraient normalement éliminés par les conditions de modulo 60, donc de nombreux composites contenant 25 comme facteur doivent être éliminé le premier des 5 place de libre. De même, 55 passe le contrôle" 3x+ "et 35 passe le contrôle" 3x - " où ils pas pour l'algorithme complet de modulo 60.

comme discuté dans L'article de Wikipedia "Talk" section et laissé entendre ci-dessus, ce pseudo code Cité n'est jamais beaucoup plus rapide que même la cote de base seulement tamis D'Eratosthenes (SoE) mises en œuvre et encore moins un qui utilise le même degré de factorisation de roue en raison de son inefficacités: les variables 'x' et' y ' n'ont pas besoin de s'étendre sur toute la gamme jusqu'à la racine carrée de la gamme tamisée dans de nombreux cas (mentionnés dans l'article), l'utilisation correcte de la roue modulo 60 récupère les redondances dans l'utilisation de la simplification modulo 12 (Comme je le mentionne ci-dessus), et il y a des modèles de réseau modulo dans les solutions aux équations quadratiques de sorte que les conditions utilisant les opérations (computationally slow) modulo ne doivent pas être testées par l'utilisation d'un algorithme cela saute automatiquement les solutions qui ne répondraient pas à ces conditions modulo selon les modèles de treillis (seulement mentionné très obscurément dans le papier complet Atkin et Bernstein).

pour répondre à une question que vous n'avez pas posée mais qui aurait dû être: " Pourquoi utiliser le tamis D'Atkin?" .

la raison principale que le tamis D'Atkin (SoA) est mis en œuvre plutôt que le tamis D'Eratosthène (SoE) est qu'il est " Connaissance Internet" que la SOA est plus rapide. Il y a deux raisons à cette croyance, comme suit:

  1. la SoA est supposée être plus rapide parce que l'asymptotic computational la complexité est moindre pour les ti que pour les ee par un facteur de log(log n) où n est la gamme de produits tamisés. Pratiquement parlant, aller à partir d'une gamme de deux à la puissance 32 (quatre milliards de plus) à deux la puissance 64 (environ 2 suivi de 19 zéros), ce facteur est de six sur cinq est égal à 1.2. Que signifie que le vrai SoE devrait prendre 1,2 fois aussi longtemps que prévu par juste un rapport linéaire lors du tamisage La gamme des nombres 64 bits par rapport à la gamme des nombres 32 bits, alors que la SoA aura une relation linéaire si tout était idéal . Vous peut comprendre que, tout d'abord, c'est un très petit facteur pour un la différence énorme dans les fourchettes de nombre et, deuxièmement, que cet avantage seulement tient si les deux algorithmes avaient le même ou proche du même performance à un niveau raisonnable la gamme de nombres premiers.

    ce qui n'est pas clairement compris par cette "connaissance D'Internet" est que ces chiffres ne s'appliquent que si l'on compare le ratio performances sur une plage donnée par rapport à une autre plage donnée pour le même algorithme , pas comme une comparaison entre différents algorithme. Il est donc inutile de prouver que la SoA sera plus rapide que le SoE puisque le SoA pourrait commencer avec un plus grand overhead pour un tamis gamme de l'algorithme SoE particulier comme dans le suivant l'exemple optimisé de SoE.

  2. on croit que la SoA est plus rapide en raison du calcul comparaison faite et publiée par Atkin et Bernstein selon leur papier lié dans L'article de Wikipedia. Bien que le travail soit précis, elle ne s'applique qu'à des limites artificielles qu'ils ont fait sur le Algorithme SoE ils ont comparé: puisque l'algorithme SoA est basé sur modulo 60 factorisation qui représente deux 2,3,5 factorisation rotations de roues, ils ont également limité l'algorithme SoE à ce même la roue de la factorisation. Ce faisant, le SoE fait environ 424 000 nombre composite d'opérations de réforme dans la gamme de 1 milliard testées, alors qu'une SoA as testée entièrement optimisée compte environ 326 000 bascule et place des opérations d'abattage, qui prennent chacun sur la même temps que chaque opération d'abattage à numéro composite dans L'entreprise D'État en raison de écrit dans le même style. Cela signifie que la SoA est 30% plus rapide que la SoE pour cet ensemble particulier de factorisation de roue conditions , et c'est exactement ce que les Atkins et Bernstein le test de comparaison a montré.

    cependant, la SoA ne répond pas à d'autres niveaux de roue factorisation comme le 2,3,5 niveau est "cuit" à l'algorithme, alors que le SoE répond à d'autres niveaux: en utilisant un 2,3,5,7 la factorisation des roues entraîne à peu près le même nombre d'opérations signification sur le même des performances de chacun. On peut utiliser même un niveau partiel de factorisation de la roue plus élevé que le niveau 2,3,5,7 pour obtenir le nombre d'opérations pour SoE environ 16,7% de moins que SoA, pour une proportionnelle de meilleures performances. Les optimisations nécessaires pour mettre en œuvre ces niveaux supplémentaires de factorisation des roues sont en fait plus simple que la complexité du code pour mettre en œuvre l'original optimisé SOA. L'empreinte mémoire pour la mise en œuvre de ces pages comparables segmenté implémentations est d'environ la même, la taille de la les tampons de page plus le tableau de base des nombres premiers.

    en outre, les deux gagneraient à être écrit dans une " machine recherche d'État " style qui aiderait à une meilleure optimisation en utilisant code inlined et boucle extrême mais le SoE convient plus de ce style que la SoA en raison d'être un algorithme plus simple.

ainsi, pour des intervalles de tamis allant jusqu'à environ 32 bits, la SoE optimisée au maximum est d'environ 20% plus rapide (ou plus avec plus de factorisation de la roue) que le SoA; cependant, le SoA a cet avantage asymptotique de complexité computationnelle, donc il y aura un certain point où il rattrape. Ce point se situera à peu près à l'intervalle où le rapport log (log n) / log (log (2^32)) ou 5 est de 1,2 ou environ 2 fois 10 à la dix - neuvième puissance-un nombre excessivement élevé. si le SOA optimisé exécuter sur un ordinateur de bureau moderne devaient prendre environ un tiers d'un en second lieu pour calculer les nombres premiers dans la gamme de nombre de 32 bits, et si la mise en œuvre étaient idéales comme en prenant augmentation linéaire du temps avec la gamme croissante, il faudrait environ 45 ans pour calculer les nombres premiers à cette gamme. Cependant, l'analyse des nombres premiers dans ces fourchettes élevées est souvent faite en petits morceaux, pour lesquels l'utilisation de L'AAS serait théoriquement pratique par rapport à L'EAS pour les tamis à très grand nombre, mais par un facteur très petit.

EDIT_ADD: en fait, ni la page segmentée SoE ni la SoA continuent à courir dans le temps linéaire pour ces énormes gammes par rapport aux gammes inférieures car les deux courent dans des problèmes avec les opérations" basculement "et" culling "perte d'efficacité en raison de devoir sauter un grand nombre de pages par saut; cela signifie que les deux nécessiteront des algorithmes modifiés pour gérer ce "saut de page" et le très léger avantage de la SoA peut être complètement effacé s'il y a sont tout de légères différences dans la façon dont cela se fait. La SoA a beaucoup plus de termes dans les "sauts tables" que la SoE par environ le rapport inverse entre le nombre de nombres premiers trouvés jusqu'à la racine carrée de la gamme à cette gamme, et cela ajoutera probablement un terme O(log n) aux deux dans le traitement mais un facteur constant plus grande augmentation pour la SoA qui a un plus grand nombre d'entrées dans le "saut table". Ce fait supplémentaire annulera à peu près complètement tout avantage de la SoA sur le SoE, même pour des gammes extrêmement grandes. De plus, L'AAS a un plafond constant d'un plus grand nombre de boucles individuelles requises pour les nombreux cas supplémentaires dans la mise en œuvre des conditions pour les trois équations quadratiques séparées plus la boucle "prime squares free" au lieu d'une simple boucle d'abattage de primes ne peut donc jamais avoir un temps de calcul moyen aussi bas par opération que L'EAS lorsque pleinement optimisé. END_EDIT_ADD

EDIT_ADD2: It est-ce que je pense qu'une grande partie de la confusion au sujet du tamis D'Atkin est due aux déficiences du pseudo-code de L'article de Wikipedia cité dans la question, donc ont mis au point une version un peu meilleure du pseudo-code qui traite au moins certaines des déficiences à faire avec la gamme des variables 'x' et 'y' et la confusion modulo 12 versus modulo 60 comme suit:

limit ← 1000000000        // arbitrary search limit

// Initialize the sieve
for i in {7,11,13,17,19,23,29,31, 37,41,43,47,49,53,59,61,...}:
    is_prime(i) ← false

// Put in candidate primes:
// integers which have an odd number of
// representations by certain quadratic forms.
while n ≤ limit, n ← 4x²+y² where x ∈ {1,2,...} and y ∈ {1,3,...} // odd y's
    if n mod 60 ∈ {1,13,17,29,37,41,49,53}:
        is_prime(n) ← ¬is_prime(n)
while n ≤ limit, n ← 3x²+y² where x ∈ {1,3,...} and y ∈ {2,4,...} // only odd 
    if n mod 60 ∈ {7,19,31,43}:                            // x's and even y's
        is_prime(n) ← ¬is_prime(n)
while n ≤ limit, n ← 3x²-y² where x ∈ {2,3,...} and y ∈ {x-1,x-3,...,1} //all 
    if n mod 60 ∈ {11,23,47,59}:                   // even/odd odd/even combos
        is_prime(n) ← ¬is_prime(n)

// Eliminate composites by sieving, only for those occurrences on the wheel
for n² ≤ limit where n ∈ {7,11,13,17,19,23,29,31, 37,41,43,47,49,53,59,61,...}:
    if is_prime(n):
        // n is prime, omit multiples of its square; this is
        // sufficient because composites which managed to get
        // on the list cannot be square-free
        while c ≤ limit, c ← n² × k where
                      k ∈ {1,7,11,13,17,19,23,29, 31,37,41,43,47,49,53,59,...}:
            is_prime(c) ← false

output 2, 3, 5
for n ≤ limit when n ← 60 × k + x where
  k ∈ {0..} and
  x ∈ {7,11,13,17,19,23,29,31, 37,41,43,47,49,53,59,61}:
    if is_prime(n): output n

ce qui précède semble assez simple et est tout à fait un bon algorithme sauf qu'il n'est pas encore plus rapide qu'un tamis de base D'Eratosthènes qui utilise la même roue de factorisation 2;3;5 parce qu'il gaspille presque la moitié de ses opérations de basculement de boucle interne qui échouent les essais modulo. Pour démontrer:

ci-dessous est le motif répété 4x2+y2 du modulo 60 qualifiant dans une gamme de 15 valeurs de 'x' (chaque valeur) verticalement et 15 valeurs impaires de 'y' horizontalement; les deux commençant à un. Remarquez qu'ils sont symétriques par rapport à un axe vertical, mais seulement 128 sur 225 ou 256 sur 450 pour une gamme complète de 30 nombres de valeurs "x" sont des opérations de basculement valides:

  0 13 29 53  0  0 53 49 53  0  0 53 29 13  0
 17  0 41  0 37 17  0  1  0 17 37  0 41  0 17
 37  0  1  0  0 37  0  0  0 37  0  0  1  0 37
  0 13 29 53  0  0 53 49 53  0  0 53 29 13  0
 41 49  0 29  1 41 29  0 29 41  1 29  0 49 41
  0  0 49 13  0  0 13  0 13  0  0 13 49  0  0
 17  0 41  0 37 17  0  1  0 17 37  0 41  0 17
 17  0 41  0 37 17  0  1  0 17 37  0 41  0 17
  0  0 49 13  0  0 13  0 13  0  0 13 49  0  0
 41 49  0 29  1 41 29  0 29 41  1 29  0 49 41
  0 13 29 53  0  0 53 49 53  0  0 53 29 13  0
 37  0  1  0  0 37  0  0  0 37  0  0  1  0 37
 17  0 41  0 37 17  0  1  0 17 37  0 41  0 17
  0 13 29 53  0  0 53 49 53  0  0 53 29 13  0
  1  0  0 49  0  1 49  0 49  1  0 49  0  0  1

ci-dessous est le motif répétitif 3x2+y2 du modulo 60 qualifiant dans une gamme de 5 valeurs impaires de 'x' verticalement et 15 valeurs égales de 'y' horizontalement. Remarquez qu'ils sont symétriques par rapport à un axe horizontal mais seulement 48 sur 75 ou 144 sur 450 pour une gamme complète de 30 nombres de valeurs de "x" sont des opérations de basculement valides puisque les 144 sur 450 invalides les opérations avec "X" Pair et " y "Impair ont déjà été éliminées:

  7 19  0  7 43  0 19 19  0 43  7  0 19  7  0
 31 43  0 31  7  0 43 43  0  7 31  0 43 31  0
 19 31  0 19  0  0 31 31  0  0 19  0 31 19  0
 31 43  0 31  7  0 43 43  0  7 31  0 43 31  0
  7 19  0  7 43  0 19 19  0 43  7  0 19  7  0

ci-dessous est le motif répétitif 3x2-y2 du modulo 60 de qualification à travers une gamme de 5 valeurs impaires de 'x' verticalement et 15 valeurs égales de 'y' horizontalement. Remarquez qu'elles sont symétriques par rapport à un axe horizontal mais que seulement 48 sur 75 ou 224 sur 450 pour une gamme complète de 30 nombres de valeurs de " x "sont des opérations de basculement valables:

 59 47  0 59 23  0 47 47  0 23 59  0 47 59  0
 23 11  0 23 47  0 11 11  0 47 23  0 11 23  0
 11 59  0 11  0  0 59 59  0  0 11  0 59 11  0
 23 11  0 23 47  0 11 11  0 47 23  0 11 23  0
 59 47  0 59 23  0 47 47  0 23 59  0 47 59  0

répétition du schéma 3x2-y2 du modulo 60 qualificatif sur une plage de 5 valeurs paires de ' x ' verticalement et 15 valeurs impaires de 'y' horizontalement. Remarquez qu'elles sont symétriques par rapport à un axe vertical, mais seulement 48 sur 75 ou 224 sur 450 pour une gamme complète de 30 nombres de valeurs " x "sont des opérations de basculement valides:

 11  0 47 23  0 11 23  0 23 11  0 23 47  0 11
 47  0 23 59  0 47 59  0 59 47  0 59 23  0 47
 47  0 23 59  0 47 59  0 59 47  0 59 23  0 47
 11  0 47 23  0 11 23  0 23 11  0 23 47  0 11
 59  0  0 11  0 59 11  0 11 59  0 11  0  0 59

comme on peut le déterminer par l'inspection des tableaux ci-dessus, pour le pseudo-code comme ci-dessus il y a une plage de répétition globale de 30 valeurs de x (y compris en effet, il n'y a que 688 opérations valables sur un total de 1125 opérations combinées; il gaspille ainsi près de la moitié de son traitement en sautant juste conditionnellement sur des valeurs en raison des opérations de sauts improductifs faisant partie des boucles internes.Il y a deux méthodes possibles pour éliminer cette redondance "hit" inefficace, comme suit:

  1. la méthode décrite dans le document Atkin et Bernstein, qui utilise la méthode reconnue les modèles dans les modulos combinés de 'x' et 'y' pour traiter seulement le modulo "hits" en utilisant le fait qu'une fois qu'on localise un modulo donné sur le modèle, alors il y a une séquence infinie de valeurs à cela un certain modulo (égale la position de la roue bit) où chaque modèle est séparé par un calcul facile (variable) offset qui a la forme "position courante plus A fois la valeur courante de' x 'plus B" et "position courante plus C fois la valeur courante de 'y' plus D" où A, B, C, Et D, sont constantes simples (signification simple petite facilement manipulable). Bernstein utilisé cette méthode avec l'aide de plusieurs Tables (Lut).

  2. la méthode de création des tables de recherche d'état de modèle global (lut) (une pour chacune des quatre tables ci-dessus plus une pour la boucle libre prime square) indexées par les valeurs de courant modulo de 'x' combinées avec le modulo de' y ' pour trouver les Paramètres A, B, C, et D à sauter, et non pas au prochain modèle, mais juste pour la position suivante sur la séquence horizontale. C'est probablement l'option la plus performante car elle permet plus facilement une réduction extrême du cycle d'horloge par opération en utilisant l'in-doublure du code de boucle non-déroulée et produira du code plus efficace pour les grandes gammes lorsque la page segmente que les sauts par boucle sont plus petits en moyenne. Cela fera probablement les cycles d'horloge par boucle proche de celle d'un tamis hautement optimisé D'Eratosthènes comme dans primesieve , mais il est peu probable qu'il atteigne un niveau aussi bas en raison de la nécessité de calculer les tailles variables des échelons plutôt que d'être en mesure d'utiliser des compensations de prime fixes pour les entreprises D'État.

il y a donc trois objectifs de réduction de la durée de fonctionnement d'un tamis primaire, comme suit:

  1. un tamis réussi réduit le nombre d'opérations que même le SoA" hit optimized " ne réussit pas par rapport à un SoE fortement factorisé d'environ 16,7% pour des fourchettes de quelques milliards.

  2. un tamis réussi réduit les cycles D'horloge CPU par opération, ce que le SoA ne réussit pas par rapport à un SoE hautement optimisé tel que primesieve parce que ses opérations sont plus complexes en raison des incréments variables, encore une fois probable de 20% à 60%. Le primegen D'Atkin et de Bernstein (SoA) prend environ 4,5 par rapport à environ 2,5 cycles d'horloge par opération pour primesieve (SoE) pour une gamme d'un milliard pour chacun, mais peut-être que L'AAS pourrait être quelque peu accéléré en empruntant certaines des techniques d'optimisation de primesieve.

  3. un tamis réussi a une complexité de code raisonnablement faible de sorte qu'il peut être plus facilement étendu à de plus grandes gammes en utilisant des techniques telles que" godet tamisage " et d'autres optimisations de segmentation de page. Pour cela le tamis D'Atkin échoue misérablement car il devient exponentiellement plus complexe pour la page segmentant de grandes gammes de nombres. Il est extrêmement complexe pour écrire un programme SoA qui serait en concurrence avec même primegen de Bernstein (SoA), et encore moins avec primesieve, alors qu'il est assez facile d'écrire du code qui se rapproche de la même performance que primesieve.

  4. un tamis réussi présente une complexité empirique plus faible, que L'AAS a au-dessus de L'EAS par un facteur de (log (log n) où n est la plage supérieure à tamiser, mais ce ratio très faible n'est probablement jamais suffisant pour faire en haut pour les deux premiers rapports de perte combinés ci-dessus, que ce facteur devient plus petit avec l'augmentation de la portée. END_EDIT_ADD2

ainsi la réponse à la question " Pourquoi utiliser le tamis D'Atkin?" est "Il n'y a pas de raison de l'utiliser du tout si le SoE est mis en œuvre avec le maximum de la roue de la factorisation des optimisations jusqu'à ce que le nombre tamisé sont extrêmement grande (64 bits gamme de nombre et plus) et puis L'avantage SoA est très petit et peut-être pas réalisable du tout en fonction de retouches très mineures dans les optimisations relatives." .

comme une réponse à une autre Tamise similaire d'Atkin question, j'ai posté une page segmenté C# version de la SoE optimisé selon le ci-dessus à: https://stackoverflow.com/a/20559687/549617 .

33
répondu GordonBGood 2017-05-23 12:26:43

Dans mon "151930920 original de la réponse à cette question , afin de les aider à mieux comprendre le Crible d'Atkin alogithm j'ai étendu le Wikipedia Crible d'Atkin (SoA) pseudo-code pour corriger certaines des lacunes dans la procédure simplifiée de "modulo 12" algorithme donné, que beaucoup trouvent difficile que par rapport à l' "modulo 60" de l'algorithme. De plus, L'algorithme original du pseudo-code de Wikipédia mène à des implémentations inefficaces; plus précisément, les plages de 'x' et les variables " y " sont chacune plus larges que nécessaire et la simplification de modulo 12 entraîne un surcroît de travail de 20%. Toutefois, comme il en a été question dans cette réponse, ce pseudo-code n'est toujours pas efficace, car les essais modulo sont toujours dans les boucles de solution quadratiques les plus internes et, par conséquent, près de la moitié de ces boucles de solution sont improductives pour les solutions qui ne passent pas les essais modulo; cela signifie qu'un programme mettant en œuvre ce pseudo-code serait probablement presque deux fois plus lent que nécessaire, même quand il n'y a pas d'accès à la mémoire vitesse d'étranglement.

l'algorithme utilisé par Atkin et Bernstein dans leur programme "primegen" pour éviter la redondance des boucles peut être mieux compris par une progression à travers les observations suivantes basées sur les tableaux " hit "dans ma réponse précédente:

  1. la symétrie des tables " hit " dépend de si 'y' est impair (symétrie verticale) ou Pair (symétrie horizontale).

  2. ainsi, si nous voulions que l'avance des motifs se déroule dans la direction horizontale comme indiqué ici, nous pouvons retourner l'ordre des boucles 'x' et 'y' pour les cas "3x+" et "3x-;Impair x -> Pair y" signifiant Impair 'x'.

  3. maintenant, il est facile d'éliminer les zéros pour les deux tables "3x" retournées qui ont seulement cinq répétitions horizontales par une condition dans une boucle externe comme les cas où " y mod 3 = 0" plus les trois cas supplémentaires seulement pour la colonne "axe" du milieu où "y mod 5 = 0".

  4. pour le dernier cas "3x -; même x - > Impair y", il est facile d'éliminer la plupart des zéros en filtrant simplement les cas où "(y + 2) mod 3 égale 0" plus les deux cas supplémentaires seulement pour la dernière ligne où "(x mod 60) égale 59 "où" (y + 2) mod 5 égale 0" (éliminations en double pour la colonne à axe vertical symétrique, qui est toujours éliminé). Bien que ces "tests y" semblent devoir se produire dans une boucle interne, comme il n'y a que cinq "hits" par côté de l'axe de symétrie verticale, ceux-ci peuvent être codés en ligne par la boucle "x".

  5. les éliminations les plus difficiles sont pour la table "4x" où le patron est plus complexe: il y a cinq patrons horizontaux distincts où chacun peut être reconnu parce que le "(x mod 60) pour la première colonne" est distinct, avec un des dans le premier tableau ci-dessus, les modèles de zéros de tête ont un modulo de 5 et l'autre un modulo de 25; maintenant, les cinq modèles différents peuvent être déterminés en "inclinant" les cas comme des décalages de chaque côté de l'axe symétrique vertical pour chaque modèle.

  6. L'espacement à la ligne suivante est exactement 4 × ((x + 1)2 - x2) ou 8x + 4 pour le premier tableau, (y + 2)2 - y2 ou 4y + 4 pour les deux (échangé), de nouvelles tables, et 3 × ((x + 2)2 - x2) ou 12x + 12 pour la dernière table.

  7. pour tous les tableaux (maintenant) à symétrie verticale, le déport de l'axe central peut être déterminé à partir du déport de la première colonne comme (y + 16)2 - y2 ou 32y + 256 pour les rangées longues et 3 × ((x + 4)2 - x2) ou 24x + 48 pour les rangées courtes.

  8. de la même manière, les décalages symétriques de part et d'autre de l'axe vertical peuvent facilement être calculés à partir du décalage de la verticale l'axe, par exemple par la paire (y + 2)2 - y2 ou 4 + 4x avec (y - 2)2 - y2 ou 4 - 4y où y est l'axe central décalé pour les cas de la rangée longue et plus et moins deux positions; le cas pour les cas de la rangée courte 'x' est similaire mais juste multiplié par trois pour l'échelle globale des valeurs "3x" 'x'.

  9. les filtres ci-dessus déterminés par des conditions horizontales variables semblent briser notre objectif d'éliminer le code conditionnel dans les boucles intérieures, mais cette règle ne s'applique pas lorsque la détermination du modèle n'est pas la boucle interne, mais commence plutôt une série entière de nouvelles boucles internes à travers tous les modèles horizontalement dans le tableau pour chaque élément valide du modèle. Cela fonctionne parce que nous pouvons montrer mathématiquement que chacun de la même position équivalente dans le prochain modèle (qui a le même modulo) sont séparés comme suit: pour les avances de modèle horizontal de 30 pour les cas de la longue rangée, les modèles sont séparés par (x + 30)2 - x2 ou 60x + 900 60 × (x + 15); pour le modèle horizontal avancées par 10 pour le court rangée cas, les motifs sont séparés par 3 × ((x + 10)2 - x2) donc 60 * (x + 5). Puisque les deux ont un modulo 60 de zéro, c'est l'explication exacte de pourquoi il y a des motifs répétés du même modulo dans chaque position. Ainsi, une fois que nous trouvons l'offset pour chaque position du coin supérieur gauche, nous pouvons déterminer le modulo et l'offset pour les emplacements de départ pour les positions de modèle non-zéro et juste rouler un intérieur boucle utilisant les relations de pattern de ce point à la limite du réseau de tamis.

  10. tous les incréments de colonne et de rangée ci-dessus peuvent être faits sans utiliser une opération de "diviser" en utilisant l'addition de modulo où l'algorithme garde la trace des paires de quotients et de modulo de 60 avec juste une opération de "contrôle de débordement et d'ajustement" sur la paire de modulo/quotient après chaque opération, mais le code conditionnel pour faire le "contrôle et d'ajustement" est probablement plus gourmand en ressources que la façon comme l'a écrit, pour lequel les plus modernes d'optimisation des compilateurs va générer une multiplication à l'aide de dépassement de la troncature des caractéristiques de remplacer le calcul coûteuse opération de division de la division par petits nombres, ce qui prend généralement moins de temps que la combinaison des opérations de plus le code conditionnel du "vérifier et régler la" méthode ou l'utilisation directe d'une opération de division.

  11. ci-dessus les séries d'éliminations fonctionnent très bien pour une représentation en bits empaquetés des nombres premiers candidats en ce sens que chacune des 16 valeurs modulo valides peut être représentée comme un bit dans un mot de 16 bits et que l'index des mots présente les index de chaque roue modulo 60; ainsi nous pouvons avancer par incréments également divisibles par 60 en avançant simplement un nombre entier de mots de 16 bits.

Pour une utilisation en tant que non-page segmenté de l'algorithme, comme pour le code de pseudo ici, c'est suffisant pour déplacer simplement les contrôles modulo hors de la boucle la plus interne sans éliminer tous les "hit misses" pour la boucle centrale résultante, comme s'ils n'étaient pas encore maximalement efficaces en ce que la boucle centrale traite toujours les "hit misses", ce qui n'ajoute pas plus d'environ un pour cent au temps d'exécution; cependant, pour les implémentations paginées, les "coups manqués", même dans les boucles externes, peuvent ajouter beaucoup à la charge de calcul, car ces boucles sont exécutées une fois par page dans la plage des valeurs de "x". pour cette page donc il y a un facteur d'environ le logarithme de la racine carrée de la gamme tamisée plus des boucles externes pour le SoA par rapport au tamis D'Eratosthène (SoE). Une version de pseudo-code plus complexe qui représente une version (éventuellement bourrée) Non segmentée de la page de la méthode" hit optimized "Atkin et Bernstein peut alors être écrit comme suit:

// arbitrary search limit
limit ← 1000000000

// the set of base wheel prime candidates
s ∈ {7,11,13,17,19,23,29,31, 37,41,43,47,49,53,59,61}

// Initialize the sieve as an array of wheels with
// enough wheels to include the representation for limit
for n ← 60 * w + x where w ∈ {0,...(limit - 7) ÷ 60}, x in s:
    sieve(n) ← false // start with no primes.

// Put in candidate primes:
// integers which have an odd number of
// representations by certain quadratic forms.
while n ≤ limit when n ← 4x²+y²            // all x's and only odd y's
        where x ∈ {1,...}, y ∈ {1,31,...}: // skip by pattern width in y
    for cb ≤ limit when midy ← y + i, cb ← n - y² + midy²
            where i ∈ {0,2,...28}: // middle level loop to "hit" test modulos
        cbd ← (cb - 7) ÷ 60, cm ← cb mod 60
        if cm in {1,13,17,29,37,41,49,53}:
            while c ≤ limit when c ← 60 × (cbd - midy² + ((midy + 15 × j) × j)²) + cm
                    where j  {0,...}:
                sieve(c) ← ¬sieve(c) // toggles the affected bit
while n ≤ limit when n ← 3x²+y²              // only odd x's and even y's
        where x ∈ {1,3,...}, y ∈ {2,32,...}: // skip by pattern width in y
    for cb ≤ limit when midy ← y + i, cb ← n - y² + midy²
            where i ∈ {0,2,...28}: // middle level loop to "hit" test modulos
        cbd ← (cb - 7) ÷ 60, cm ← cb mod 60
        if cm in {7,19,31,43}:
            while c ≤ limit when c ← 60 × (cbd - midy² + ((midy + 15 × j) × j)²) + cm
                    where j  {0,...}:
                sieve(c) ← ¬sieve(c) // toggles the affected bit
while n ≤ limit when n ← 3x²-y²                    //even/odd & odd/even combos
        where x ∈ {2,3,...}, y ∈ {x-1,x-31,...,1}: // skip by pattern width in y
    for midy ≥ 1 and cb ≤ limit when midy ← y - i, cb ← n + y² - midy²
            where i ∈ {0,2,...28}: // middle level loop to "hit" test modulos
        cbd ← (cb - 7) ÷ 60, cm ← cb mod 60
        if cm in {11,23,47,59}:
            while yn ≥ 1 and c ≤ limit when yn = midy - 30 * j and
                             c ← 60 × (cbd + midy² - ((midy - 15 × j) × j)²) + cm
                    where j  {0,...}:
                sieve(c) ← ¬sieve(c) // toggles the affected bit

// Eliminate prime squares by sieving, only for those occurrences on the wheel
for sqr ≤ limit where sqr ← n², n in {7,11,13,17,19,23,29,31, 37,41,43,47,49,53,59,61,...}:
    if is_prime(n):
        // n is prime, omit multiples of its square; this is
        // sufficient because composites which managed to get
        // on the list cannot be square-free
        if c0 ≤ limit where c0 ← sqr × (m mod 60) where m in s:
            c0d ← (c0 - 7) ÷ 60, cm ← (c0 - 7) mod 60 + 7 // means cm in s
            while c ≤ limit for c ← 60 × (c0d + sqr × j) + cm
                    where j ∈ {0,...}:
                sieve(c) ← false       // cull composites of this prime square

output 2, 3, 5
for n ≤ limit when n ← 60 × k + x where k ∈ {0..}, x in s:
    if sieve(n): output n

en particulier, remarquez comment les boucles quadratiques les plus profondes sont très simples mais incrémentielles par une quantité variable linéairement croissante par boucle, alors que l'élimination libre des carrés premiers, qui utilise un type de progression des Eratosthènes, augmente par une quantité fixe "sqr". Ces boucles simples s'exécuteront très rapidement sur un CPU moderne, prenant environ 4 cycles d'horloge CPU par boucle si l'accès à la mémoire est assez rapide comme pour les petites gammes de tamis ou comme dans l'utilisation d'une version segmentée de page où les pages s'inscrivent dans les caches de CPU L2/L1 qui ont des temps d'accès à la mémoire d'environ cette gamme.

quand le tableau est grand comme dans beaucoup de mégaoctets, alors le temps moyen d'accès à la mémoire est susceptible de moyenne quelque chose entre 20 et plus de 100 cycles D'horloge CPU (en fonction de la vitesse de la RAM, l'efficacité de l'accès à la mémoire par le CPU, et l'efficacité de l'utilisation des caches intermédiaires) et ce sera le principal facteur limitant dans la vitesse d'exécution plutôt que l'étanchéité des boucles autre que le nombre d'opérations de bascule/cull que l'algorithme exige. Ces algorithmes particuliers, à la fois SoA et SoE, exercent une pression particulière sur l'interface mémoire pour les gros tampons en ce sens qu'ils passent à travers le tampon incrémentant par des circonférences de roue entières fois un multiplicateur à la fois et répètent pour des décalages différents plutôt que de gérer tous les "coups" de la roue dans l'ordre; ceci est dû au déplacement des tests de "coups" dans une boucle du milieu, ce qui permet d'éviter les tests de "coups" mais a pour conséquence un plus grand "saut" de tampon, avec le "saut" moyen pour le SoA plus élevé que pour le SoE. Ainsi, un l'estimation du temps d'exécution de cet algorithme sur la gamme de nombres à un milliard est d'environ 60 cycles d'horloge CPU par opération (qui sera moins d'un facteur pour L'ee en raison d'un plus petit "saut" moyenne) multiplié par le nombre d'opérations de bascule/cull (environ 260.000 pour le tamis D'Atkin) divisé par la vitesse D'horloge CPU. Par conséquent, un CPU de 3,5 GHz exécutera cet algorithme dans une plage allant jusqu'à un milliard en environ quatre secondes et la principale différence entre la vitesse d'exécution pour les non-Pagés les implémentations de la SoA et de la SoE dans ce style est la différence dans l'efficacité d'accès à la mémoire pour les gros tampons, où une SoE fortement factorisée est plus efficace d'environ un facteur de deux.

étant donné que pour les gros tampons le temps d'accès à la mémoire est le facteur de vitesse limite, il devient très important de trouver un algorithme avec un nombre minimal d'opérations. La SoA mise en œuvre par Atkin et Bernstein dans leur programme d'échantillonnage "primegen" prend environ une constante facteur d'opérations "hit" comme un rapport à la gamme tamisée, et en mettant en œuvre même une version simple d'un programme de ma première réponse, nous pouvons déterminer que ce facteur est d'environ 0,26 de la gamme premier tamisé: ce qui signifie qu'il ya environ 260.000 opérations pour une gamme tamisée d'un milliard.

pour un SoE mis en œuvre avec une grande factorisation de roue d'une roue de 210 éléments avec 48 "hits" de candidat principal par rotation (petite roue pour des nombres premiers de 2;3;5;7) en combinaison avec un pré-élimination par les nombres premiers supplémentaires de 11; 13; 17; 19, le nombre d'opérations d'élimination pour une gamme de tamis n est approximativement n fois (ln (((ln n) / 2) + M - 1 / (ln n) - 1/2 - 1/3 - 1/5 - 1/7 - 1/11 - 1/13 - 1/17 - 1/19) * 48 / 210 où " * "signifie multiplié par," / " signifie divisé par, M est la constante de Meissel-Mertens m ≈ 0,2614972128... si l'on corrige le nombre d'opérations découlant de l'estimation (ln n), le terme "LN n" réciproque est l'Ajustement pour l'abattage à partir du carré de la base. primes (moins que la racine carrée de la gamme n); pour n d'un milliard, le facteur par rapport à n est d'environ 0,250485568 ou environ 250 millions d'opérations de réforme pour une gamme allant jusqu'à un milliard.

c'est à peu près le même nombre d'opérations que pour la SoA et contraste avec la simple 2;3;5 roue utilisée dans le test de comparaison Atkin et Bernstein, qui a un facteur de 0.404805008 ou environ 400.000 opérations pour une gamme de tamis d'un milliard. Ce meilleur rapport pour les l'Ede factorisée signifie que les facteurs constants pour cette mise en œuvre tout à fait réalisable sont à peu près les mêmes que pour l'aos, sauf pour les différences dans les facteurs constants en raison de la complexité de la boucle.

EDIT_ADD1: pour comparaison, le code pseudo suivant est équivalent pour un SoE hautement factorisé et présélectionné écrit dans le même style que l'algorithme SOA ci-dessus:

// arbitrary search limit
limit ← 1000000000

// the set of base wheel primes
r ∈ {23,29,31,37,41,43,47,53, 59,61,67,71,73,79,83, //positions + 19
     89,97,101,103,107,109,113,121,127, 131,137,139,143,149,151,157,163,
     167,169,173,179,181,187,191,193, 197,199,209,211,221,223,227,229}

// an array of length 11 times 13 times 17 times 19 = 46189 wheels initialized
// so that it doesn't contain multiples of the large wheel primes
for n where n ← 210 × w + x where w ∈ {0,...46189}, x in r: // already
    if (n mod cp) not equal to 0 where cp ∈ {11,13,17,19}: // no 2,3,5,7
        mstr(n) ← true else mstr(n) ← false                // factors

// Initialize the sieve as an array of the smaller wheels with
// enough wheels to include the representation for limit
for n where n ← 210 × w + x, w ∈ {0,...(limit - 19) ÷ 210}, x in r:
    sieve(n) ← mstr(n mod (210 × 46189))    // init pre-culled primes.

// Eliminate composites by sieving, only for those occurrences on the
// wheel using wheel factorization version of the Sieve of Eratosthenes
for n² ≤ limit when n ← 210 × k + x where k ∈ {0..}, x in r
    if sieve(n):
        // n is prime, cull its multiples
        s ← n² - n × (x - 23)     // zero'th modulo cull start position
        while c0 ≤ limit when c0 ← s + n × m where m in r:
            c0d ← (c0 - 23) ÷ 210, cm ← (c0 - 23) mod 210 + 23 //means cm in r
            while c ≤ limit for c ← 210 × (c0d + n × j) + cm
                    where j ∈ {0,...}:
                sieve(c) ← false       // cull composites of this prime

output 2, 3, 5, 7, 11, 13, 17, 19,
for n ≤ limit when n ← 210 × k + x where k ∈ {0..}, x in r:
    if sieve(n): output n

notez combien ce code est moins complexe en dépit du fait qu'elle est plus fortement factorisée par la roue, de sorte qu'il y a moins d'opérations aériennes constantes que le code SoA, alors que la boucle d'abattage la plus interne est en fait un peu plus simple et donc (s'il y a lieu) un peu plus rapide. Remarquez également combien de boucles externes supplémentaires doivent être exécutées pour le code SoA dans Il ya un total d'à peu près le même nombre de boucles externes que la racine carrée de la gamme de tamisage pour la SoA où il ya seulement environ la gamme de tamis divisé par le logarithme naturel de la racine carrée de cette gamme boucles extérieures pour les SoE - un facteur d'environ dix fois moins pour les SoE que pour les SOA pour les criblures de gamme d'un milliard. C'est le compromis que fait la SoA: plus de boucles externes pour moins d'opérations par boucle interne avec de plus grands "sauts" de tampon entre les opérations; cependant, c'est aussi ce qui rend la SoA moins efficace par opération, en particulier pour les plus grandes gammes de tamis. END_EDIT_ADD1

As à la complexité du code pour les plus grandes gammes, celles-ci sont toujours implémentées comme des tamis segmentés par page afin d'éviter la nécessité d'avoir tout le réseau de tamis en mémoire RAM (les contraintes de mémoire limiteraient la portée) et afin de tirer profit de la localisation de la mise en cache CPU pour réduire les temps moyens d'accès à la mémoire comme discuté ci-dessus. Pour la SoE, cela peut facilement être mis en œuvre à partir d'une copie sauvegardée de la représentation des nombres premiers de la base où il y a approximativement la racine carrée de la gamme divisé par log de ce nombre racine carrée de cette gamme; pour la SoA on doit se référer à cette même représentation des nombres premiers pour l'élimination libre des carrés premiers mais aussi utiliser les valeurs des décalages de séquence plus les valeurs sauvegardées de 'x' ou 'y' (ou sauvegarder les valeurs courantes de 'x' et 'y') afin de reprendre à la page suivante offset avec un nombre total de séquences sauvegardées comme environ la racine carrée de la gamme (non divisé par le logarithme naturel de la racine n), ou alternativement nouveau 'x' / 'y' les offsets de paire peuvent être calculés pour le début de chaque nouvelle page à une hauteur de calcul considérable. La première méthode ajoute beaucoup à l'utilisation de la mémoire au-dessus de la tête, en particulier pour les implémentations multi-threadées où une copie doit être conservée pour chaque thread; la seconde n'utilise pas plus de mémoire mais utilise plus de puissance de calcul par rapport à la SoE pour ces plus grandes gammes.

page segmenté algorithmes sont également importants afin de tirer pleinement avantage de multi-core moderne CPU qui peut réduire le temps d'horloge nécessaire pour une tâche donnée par le rapport du nombre de cœurs utilisés, en particulier pour la page divisé algorithmes où chaque traitement de page peut être assignée à un thread séparé.

la façon dont l'implémentation" primesieve " SOE gère des temps de fonctionnement moyens d'environ 2,5 cycles d'horloge CPU par rapport à environ 4,5 cycles D'horloge CPU pour L'implémentation "primegen" d'Atkin et de Bernstein est par l'in-doublure extrême de la boucle cette technique peut également être appliquée à la SoA, mais ce pseudo-code en particulier n'est pas adapté pour le faire et une autre technique d'optimisation "hit rate" qui gère tous les modulos en une seule boucle (par boucle d'équation quadratique) doit être utilisée; cependant, c'est un algorithme complexe qui semble être au-delà de la portée de cette question. Il suffit de dire que les sauts en complexité jusqu'à présent ne sont rien par rapport à ce qui est nécessaire pour ajouter ce l'optimisation supplémentaire à la SoA, et même avec cela le rapport des boucles externes rend encore la SoE beaucoup plus efficace.

ainsi, alors qu'il est assez facile de mettre en œuvre un algorithme SOA naïf comme dans le pseudo-code Wikipédia original ou même en utilisant le pseudo-code SoA plus complexe comme dans ces deux réponses, il est extrêmement complexe d'écrire quelque chose qui serait en concurrence avec même "primegen" (SoA) de Bernstein, et encore moins avec le plus rapide "primesieve" (SoE), alors qu'il est assez facile de Ecrire du code qui se rapproche de la même performance que " primegen "et juste un peu plus de travail pour écrire quelque chose qui rivalise avec" primesieve " en utilisant l'algorithme SoE avec les légères modifications pour supporter la segmentation de la page.

EDIT_ADD2: pour mettre cette théorie en pratique, j'écrirais normalement un programme d'exemple pour démontrer ces principes; cependant, dans ce cas, nous avons tout ce dont nous avons vraiment besoin dans le " primegen" code source , qui est la mise en œuvre de référence par les inventeurs de la SoA. Sur ma machine (i7-2600K, 3,5 GHz) avec la taille de tampon ajustée à 32768 à partir de 8192 pour refléter ma taille de cache L1, cette "primespeed" Tamise les primes à un milliard en environ 0,365 secondes. En fait, Atkin et Bernstein ont triché un peu dans leur comparaison avec leur algorithme de tamis Eratosthenes en ce sens qu'ils n'ont attribué qu'environ quatre tampons de kilobytes à cet algorithme; en ajustant cette taille de tampon à environ la même taille (le" #define B32 1001 "à" # define B32 8008") résulte en un temps d'exécution d'environ 0,42 secondes pour" eratspeed " à environ un milliard, le laissant encore un peu plus lent. Toutefois, comme nous l'avons vu plus haut, elle fait plus de travail en effectuant environ 0,4048 milliard d'opérations de réforme, alors que la SoA n'effectue qu'environ 0,26 milliard d'opérations combinées de réforme et de réforme. En utilisant l'algorithme du pseudo-code de SoE ci-dessus pour changer Ceci est ont factorisation maximale de roue signifie que le SoE serait en fait faire un peu moins de fonctionnement que le SoA à environ 0,2505 milliards, ce qui signifie que le temps d'exécution serait réduit à environ deux tiers ou plus ou à environ 0,265 à 0,3 secondes ce qui le rend plus rapide que "primegen".

entre-temps, si l'on compare le "primespeed" au code "eratspeed", on constate que le SoE Pagé est beaucoup moins complexe que le code SoA, comme l'indique le pseudo-code ci-dessus.

bien sûr, on pourrait contrer que le SoA maintient le rapport de 0,26 fois la gamme de tamisage opérations à une gamme de tamisage aussi élevé que l'on veut tandis que le rapport SoE Monte selon les équations ci - dessus-d'environ 20% supplémentaire pour une gamme de tamisage même à cent milliards. Toutefois, compte tenu d'un léger ajustement aux deux algorithmes pour augmenter la taille du tampon et "sub slice" it pour le traiter dans les caches de L1 tranches de taille, L'État de L'économie fonctionnera comme prévu tandis que le plafond de L'État de L'économie continue d'augmenter en raison du rapport supplémentaire de boucles moyennes / internes pour L'État de L'économie par rapport à la SoE. Alors que L'entreprise D'État enregistre une augmentation des opérations d'abattage d'environ 20%, L'entreprise D'État enregistre une augmentation des boucles quadratiques de traitement d'environ 20% pour un gain net très faible, le cas échéant. Si ces optimisations ont été faites à la SoA, alors il pourrait juste rattraper la roue factorisée SoE maximale à une gamme de tamisage très large tels que dix à la dix-neuvième puissance ou plus, mais nous parlons des centaines d'années de traitement sur un ordinateur de bureau même en utilisant le multi-traitement.

SoA pourrait pratique pour le tamisage à un sous-intervalle (ie. un segment d'une page) à partir d'une très grande plage de décalage (disons dix surélevé à la puissance de vingt-deuxième), mais il ya encore ce coût de mémoire supplémentaire ou de calcul dans le traitement de toutes les valeurs de " x " et " y " qui ne sont pas nécessaires avec le SoE. END_EDIT_ADD2

comme pour ma première réponse, la comparaison dit que SoA perd à la roue fortement factorisée SoE sur presque tous les fronts, comme suit:

  1. le code SoA est beaucoup plus complexe et il est plus difficile d'écrire et de maintenir, donc beaucoup plus difficile de mettre en œuvre la segmentation de page qui est si importante pour les plus grandes gammes afin de tirer profit des capacités CPU maximum comme les vitesses d'accès à la mémoire.

  2. le SoA perd probablement sur les cycles D'horloge CPU d'au moins 20% en raison de code de boucle interne légèrement plus complexe et un nombre plus élevé de boucles externes.

  3. la SoA a un peu plus d'opérations qu'une SoE fortement factorisée (plus grande factorisation de la roue que selon la discussion ci-dessus) pour une gamme raisonnablement grande de un à quatre milliards.

  4. la SoA gagne pour de très grandes gammes en ayant un facteur d'amélioration de log (log n) que les gammes deviennent plus grandes, mais que facteur ne permettrait à la SoA de rattraper la SOE fortement factorisée à une gamme de nombre très élevé (peut-être à environ 10 soulevé à la dix-neuvième puissance) si jamais, Et alors seulement si la complexité relative reste la même, ce qui n'est pas susceptible de faire.

Donc, je dis à nouveau: " Pourquoi utiliser le Crible d'Atkin quand le Crible d'Eratosthène est mieux dans presque tous les égards et, en particulier, est moins complexe, tout en ayant moins d'une constante facteur computationnel frais généraux? " basé sur mes conclusions ici que je sens que le SoA est un tamis inférieur pour toute sorte de gamme de tamis raisonnable et ne sera probablement jamais écrire une version segmentée de la page du tamis D'Atkin, mais ont écrit beaucoup d'entre eux dans divers langages informatiques pour le tamis D'Eratosthène. Alors que le tamis D'Atkin est intéressant intellectuellement et mathématiquement, il n'est pas vraiment pratique et la comparaison D'Atkin et de Bernstein a été défectueux en trop restrictif la factorisation de roue de leur mise en œuvre du tamis D'Eratosthène utilisés dans leur comparaison pour montrer un avantage d'environ 30%, qui aurait dû être en fait environ 60% autre que pour la mise en œuvre constante des têtes du tamis d'Atkin.

16
répondu GordonBGood 2017-05-23 12:10:54