C++11 de la mise en Œuvre de Spinlock à l'aide de <atomic>

J'ai mis en place SpinLock classe, comme suit

struct Node {
    int number;
    std::atomic_bool latch;

    void add() {
        lock();
        number++;
        unlock();
    }
    void lock() {
        bool unlatched = false;
        while(!latch.compare_exchange_weak(unlatched, true, std::memory_order_acquire));
    }
    void unlock() {
        latch.store(false , std::memory_order_release);
    }
};

J'ai mis en place au-dessus de la classe et fait deux threads appel de méthode add() d'une instance de classe de Nœud de 10 millions de fois par thread.

le résultat est , malheureusement, pas plus de 20 millions de dollars.
Ce qui me manque ici?

  • Soyez averti, c'est la pire spinlock vous pouvez éventuellement mettre en œuvre. Parmi les autres problèmes: 1) Lorsque vous enfin faire acquérir les lock, vous prenez la mère de toutes les mispredicted branches en laissant la while boucle, ce qui est le pire moment possible pour une telle chose. 2) La lock fonction peut affamer l'autre thread en cours d'exécution dans la même cœur virtuel sur un serveur hyper-thread CPU.
  • Merci pour vos commentaires. Puis-je demander de plus sur les problèmes que vous avez évoqués? 2). Que la fonction de verrouillage peut mourir de faim un autre thread, (c'est vrai!, et il est destiné à faire depuis que je suis sûr que le verrouillage de la durée de vie est très courte). Je peux utiliser des spin compteurs est ce problème, ai-je le droit? 1). Pourquoi je prendre "la mère de toutes les mispredicated brabches" dans ce code?, et comment puis-je l'améliorer?? avez-vous des commentaires à ce sujet? Merci encore
  • 2) Pas. Aucune de ces choses résoudre le problème. À l'aide de la pause instruction n'. 1) Parce que le CPU prédit le while boucle pour garder la boucle. Et, comme il arrive, vous pouvez également corriger cela avec la pause instruction.
  • J'ai obtenu ce que vous voulez dire. Peut-être que j'ai besoin de quelques recherches sur google pour comprendre comment "pause" fonctionne et comment éviter les erreurs de prédiction de branche.
  • Pause permet spéculative de l'exécution, en éliminant les erreurs de prédiction de la direction générale de la peine. (Et, en passant, si vous ne connaissez pas ce genre de trucs à l'intérieur, vous n'avez rien écrit spinlocks. Vous pourrez faire toutes les erreurs et ne pas réaliser que vous avez eu d'autres choix.)
  • Je suis intéressé par l'écriture de ces sortes de choses, mais je ne sais pas ce genre de choses à l'intérieur. Pouvez-vous recommander la façon dont une personne peut se faire connaître cet intérieur?
  • Je n'ai pas vraiment une bonne réponse à cela, d'autres que d'étudier soigneusement la qualité du travail des autres et d'acquérir beaucoup d'expérience. Ce n'est pas vraiment une piscine amateurs peuvent jouer, au-delà de l'écriture jouet code. Je me suis seulement en savons assez pour être dangereux. 😉
  • Il semble que la seule façon de devenir suffisamment compétent pour être autorisé à essayer d'écrire ce genre de code est d'essayer d'écrire ce genre de code.
  • Eh bien, il n'y a jamais de mal à essayer de faire tout type de codage. Juste avoir des attentes réalistes pour la qualité de ce que vous produisez et ne vous leurrez pas en pensant que vous êtes en train de faire, sauf si vous êtes. Dans une certaine mesure, c'est comme rouler votre propre chiffrement. Il est très facile à faire mal et parfois très difficile à point de ce qui est mauvais à propos d'un effort particulier. Beaucoup trop de gens pensent que c'est facile ou ce que vous devriez faire.
  • Qui le verrou de rotation de la mise en œuvre recommanderiez-vous? Ni les mst ni boost offre une, de sorte qu'il n'est pas évident. La folie a quelques choses, google a certaines choses, elles offrent toutes une bonne quantité de plus que ce qui est strictement nécessaire. Je serais intéressé par un simple verrou de rotation qui pourrait inclure la pause, aussi bien comme quelque chose d'un peu plus élaboré qui fournit également un bool is_locked fonction, basée sur std::atomic<bool> par exemple.
  • Vous pouvez en écrire un pour un CPU et de la plate-forme. Vous ne pouvez pas écrire un portable. Par exemple, sur les systèmes x86, vous devez émettre un pause instruction (rep nop) dans la boucle interne. Il n'existe pas de portable façon de le faire-vous avez besoin de CPU expertise.

InformationsquelleAutor syko | 2014-10-27