12
votes

Quelqu'un peut-il expliquer des fils?

J'ai envisagé d'ajouter des procédures filetées à mon application pour accélérer l'exécution, mais le problème est que je n'ai aucune idée de savoir comment utiliser des threads ou ce qui est considéré comme "fil sûr". Par exemple, comment un moteur de jeu utilise-t-il des threads dans ses processus de rendu ou dans quels contextes ne seront-ils considérés que comme un obstacle? Quelqu'un peut-il indiquer la voie à des ressources pour m'aider à apprendre plus ou à expliquer ici?


3 commentaires

C'est extrêmement général. Un fil est juste un travailleur qui exécute des commandes. "Sécurité du fil" veille à ce que deux fils ou plus ne causent pas de problèmes lorsqu'ils interagissent. En ce qui concerne un moteur de jeu utilisant des threads ... Il y a environ un million de façons de le faire.


Pour être franc. Oubliez d'ajouter des discussions. C'est comme dire que vous avez une compréhension de base des premiers secours et que vous voulez faire une chirurgie cérébrale. Retournez et apprenez les bases.


Cette question est trop large pour être répondue de manière raisonnable.


10 Réponses :


0
votes

Il y a un beau livre, Concurrence Java dans la pratique , http: //www.javaconcurencyinoctitude .com / .


2 commentaires

Bien que ce soit un livre génial, il suppose une connaissance préalable des mécanismes de base de la concurrence en Java, que l'administrateur n'est probablement pas prêt pour.


C'est vrai, j'ai oublié qu'il n'inclut pas d'intro.



1
votes

Les threads n'accélèrent pas les applications. Les algorithmes accélèrent les applications. Les fils peuvent être utilisés dans des algorithmes, le cas échéant.


4 commentaires

Les threads peuvent accélérer votre application dans certaines conditions. Tels que lorsqu'ils sont en série, les tâches de blocage peuvent être divisées en tâches parallèles. L'effet est augmenté sur les systèmes multicœurs, qui devient la norme. Considérez une tâche qui doit faire une demande TCP / IP et attendre une réponse. Si cette tâche bloque sur un thread, 10 d'entre eux prendront 10 fois l'heure. Si parallélé, cela peut être réduit à un peu plus de 1 fois la durée.


... ou est-ce juste une correction de la terminologie? :)


Ouais, j'ai étudié dans une classe d'algorithmes et j'étudie toujours des algorithmes, mais je voulais élargir mes horizons un peu plus avec des transformateurs multicœurs devenant la norme.


Pour l'électeur négatif: je suis un croyant ferme que vous introduisez seulement des threads dans un algorithme quand cela a du sens. Pas avant.



32
votes

C'est un sujet très large. Mais voici ce que je voudrais savoir si je ne connaissais rien sur les threads:

  • Ce sont des unités d'exécution dans un seul processus qui se produit "en parallèle" - ce que cela signifie que l'unité d'exécution actuelle dans le processeur passe rapidement. Cela peut être atteint via différents moyens. La commutation est appelée " Context Commutation ", et il y a des frais généraux associés à cela.

  • Ils peuvent partager la mémoire! C'est là que des problèmes peuvent survenir. J'en parle plus de profondeur d'une balle ultérieure.

  • Le bénéfice de la parallélisation de votre application est que la logique qui utilise différentes parties de la machine peut se produire simultanément. C'est-à-dire que si une partie de votre processus est liée à I / O et qu'une partie de celui-ci est liée à la CPU, l'opération intensive d'E / S n'a pas à attendre avant que l'opération intensive de la CPU soit effectuée. Certaines langues vous permettent également d'exécuter des threads en même temps si vous disposez d'un processeur multicœur (et parallèlement des opérations à forte intensité de la CPU également), bien que ce n'est pas toujours le cas.

  • Safe-Safe signifie qu'il n'y a pas de conditions de course , qui est le terme utilisé pour les problèmes qui se produisent lorsque l'exécution de votre processus dépend du calendrier (quelque chose que vous ne voulez pas compter sur). Par exemple, si vous avez des threads a et b incrémentation d'un compteur partagé C , vous pouvez voir le cas où a lit la valeur de C , puis b lit la valeur de C , puis a écrase C avec C + 1 , puis B écrasé C avec C + 1 . Notez que C n'exgrate que réellement une fois!

  • Quelques manières courantes évitent les conditions de la race incluent Synchronisation , qui exclut l'accès mutuel à l'état partagé ou ne présentant tout simplement aucun État partagé. Mais ce n'est que la pointe de l'iceberg - la sécurité du thread est un sujet assez large.

    J'espère que cela aide! Comprenez que c'était une introduction très rapide à quelque chose qui nécessite un bon apprentissage. Je recommanderais de trouver une ressource sur la multithreading dans votre langue préférée, tout ce qui se passe et de lui donner une lecture approfondie.


11 commentaires

Cela m'a aidé énormément! Merci!


+1 Bonne introduction au sujet.


@Orm: Très bienvenu; Je suis content que ce soit utile.


Cela me donne une idée de la façon de filer mon rendu. Divisez le conteneur avec les objets de jeu stockés en deux, puis deux threads rendent simultanément la première ou la seconde moitié. Ou diviser le conteneur en quartiers ou huit. Si je me trompe dans cela, arrêtez-moi maintenant.


@Orm: Je ne connais pas le développement des jeux, mais je suppose que le goulot d'étranglement est le rendu réel à l'écran? Donc, si vous avez plusieurs threads à travers les objets de jeu pour créer les tampons hors écran pour l'image et que le rendu peut échanger rapidement dans les tampons pré-calculés, cela devrait alors accélérer. Vous devez ensuite faire attention à la manière dont ces threads se séparent ensuite quels objets pour rendre, votre idée de fractionnement semble raisonnable.


Oui. Ce n'est que l'efficacité est limitée à O (n). Donc, la scission pourrait se produire dans le fil d'application principale avant que tout rendu n'a lieu, comme (les singletons sont déjà initialisés dans l'initialisation du moteur, une instance est donc garantie avant tout.) Renderer :: Instance () -> PRERenderProcess (); Rendu :: Instance () -> Rendu ();


@Orm: Je ne suis pas non plus très familier avec le rendu graphique, mais une bonne chose à retenir est que (en dehors d'un environnement multi-espèces), la vitesse d'accélération des tâches parallèle ne se produit que lorsque vous exécutez différents types de tâches en parallèle, où le type dépend de La partie de la machine qu'il utilise (voir ma troisième balle). À titre d'exemple, parallèle quelque chose comme la tresse de fusion ne donnerait aucun avantage car tout est fait dans la CPU, alors que les applications de l'interface graphique doivent être enfermées car vous ne voulez pas que le fil d'E / S permet à l'utilisateur d'interagir avec l'application pour avoir à Attendez les tâches intensives de la CPU.


D'accord, alors enfilez des choses comme la lecture de l'utilisateur de l'utilisateur et de la définir à partir du traitement graphique est quelque chose que je devrais certainement regarder est ce que vous dites?


Tout ce que je dis, c'est que vous devez vous assurer que la partie de votre application que vous souhaitez paralléliser profitera réellement d'être parallélédize. En cas de doute, vous pouvez toujours comparer et comparer.


De plus, si vous travaillez dans un environnement multi-enseignements, votre rendu graphique sera probablement en mesure de bénéficier de cela, car de nombreux jeux sont maintenant écrits pour tirer parti de plusieurs transformateurs.


@Orm: Il y a une règle générale de programmation parallèle derrière ce que Danben dit. C'est ce qu'on appelle la loi de Ahmdal et se résume à "L'augmentation de la vitesse d'une application est limitée par la fraction séquentielle". Donc, si vous devez rendant 100 objets dans la séquence , et qui prend 40% de votre boucle de rendu, il est impossible d'accélérer la boucle de plus de 60%, peu importe le nombre de threads que vous utilisez. .



1
votes

Eh bien, quelqu'un va probablement répondre à cela mieux, mais les threads sont dans le but d'avoir un traitement de fond qui ne gènait pas l'interface utilisateur. Vous ne voulez pas arrêter d'accepter l'entrée de clavier ou la saisie de la souris et indiquez à l'utilisateur: «Juste un moment, je veux terminer ce calcul, il ne s'agira que de quelques secondes.» (Et pourtant, c'est incroyable combien de fois les programmes commerciaux font cela.

En ce qui concerne le fil sûr, cela signifie une fonction qui n'a pas d'état interne enregistré. Si cela ne pouvait pas avoir plusieurs threads en l'utilisant simutanément.

En ce qui concerne la programmation du fil, vous devez simplement commencer à le faire, puis vous commencerez à rencontrer divers problèmes propres à la programmation de thread, par exemple un accès simultanéaire aux données, auquel cas vous devez décider d'utiliser une méthode de synchronisation telle En tant que sections critiques ou mutiles ou autre chose, chacun ayant des nuances légèrement différentes dans leur comportement.

En ce qui concerne les différences entre les processus et les threads (que vous n'avez pas demandé), les processus sont une entité de niveau du système d'exploitation, tandis que les threads sont associés à un programme. Dans certaines instances, votre programme peut vouloir créer un processus plutôt qu'un fil.


2 commentaires

Bien que quelque chose d'apatride soit le fil-coffre-fort, le fil-coffre-fort ne signifie pas l'apatride


Désolé, je suis dans une ambiance difficile ... "... Les fils sont dans le but d'avoir un traitement de fond qui ne gènait pas l'interface utilisateur." - Cela lit comme si c'était l'objet exclusif du threading, ce qui n'est certainement pas vrai, bien que ce soit l'une des utilisations.



1
votes

Les threads sont simplement un moyen d'exécuter plusieurs choses simultanément (en supposant que la plate-forme sur laquelle ils sont exécutés est capable d'exécution parallèle). La sécurité du fil est simplement (bien, rien avec des threads n'est vraiment simple) en veillant à ce que les fils ne s'affectent pas de manière nuisible.

En général, il est peu probable que vous voyez que les systèmes utilisent plusieurs threads pour rendu graphiques sur l'écran en raison des implications de performance multiples et des problèmes de complexité qui peuvent survenir à ce sujet. D'autres tâches liées à la gestion de l'état (ou à l'AI) peuvent potentiellement être déplacées pour séparer les threads cependant.


0 commentaires

1
votes

première règle de filetage: ne pas enfiler. Deuxième règle de filetage: Si vous devez enfreindre la règle une ... ne le faites pas. Troisième règle: OK, vous devez utiliser des threads, alors avant de procéder à votre tête dans les pièges, à comprendre le verrouillage et aux problèmes de fil courants tels que l'impasse et les volants.

Comprendre que le filetage n'accélère pas quoi que ce soit, il n'est utile que des processus long-exécutions de fond permettant à l'utilisateur de faire autre chose avec l'application. Si vous devez autoriser l'utilisateur à interagir avec l'application pendant que l'application fait quelque chose d'autre en arrière-plan, comme sondez une prise ou attendez une entrée ansynchrone d'ailleurs dans l'application, vous pouvez en effet avoir besoin de filetage.

Les sections de thread dans efficace Java et Clean Code sont de bonnes introductions aux fils et à leurs pièges.


5 commentaires

Première règle des généralisations: ne généralez pas.


MLUMITHREADING Est-ce que fournit un effort d'accélération lorsque vous avez une tâche parallelizable, liée à la CPU et il existe plusieurs processeurs (ou cœurs) disponibles. Divisez le travail dans n threads et obtenez le travail effectué dans environ 1 / n temps, où n est inférieur ou égal au nombre de processeurs.


Ceci est vrai, et plus applicable ces jours-ci avec plus de transformateurs multi-cœurs que jamais. Point pris. Mais utiliser des threads simplement pour l'optimisation, même dans des environnements multi-processeurs, c'est une proposition de dés, il est souhaitable que si votre architecture est nécessairement asynchrone, par exemple lors de la rédaction d'un serveur de quelque nature que ce soit, etc. .


Le point que j'essayais de faire (et probablement à bâcler) de "ne pas enfiler" est que le filetage introduit une foule de risques et de l'imprévisibilité de votre code de code qu'il est conseillé d'éviter si vous le pouvez éventuellement. En filetage pour son propre saké juste pour "accélérer" une application n'est pas une bonne idée, en particulier dans les environnements OO où les serrures, les mutiles et similaires peuvent créer un environnement de plus en plus complexe et imprévisible. Thar soit des dragons.


Eh bien, comme mon design initial de mon moteur de rendu s'est avéré fondamentalement défectueux de toute façon, alors des threads que je ne suis pas nécessaire après cette révision.



2
votes

Il y a quatre choses que vous devriez savoir sur les threads.

  1. Les threads sont comme des processus, mais ils partagent la mémoire.

  2. Les threads ont souvent du matériel, du système d'exploitation et du support linguistique, ce qui pourrait leur rendre meilleur que les processus.

  3. Il y a beaucoup de petites choses difficiles que les fils doivent supporter (comme des serrures et des sémaphores) afin qu'ils ne reçoivent pas la mémoire qu'ils partagent dans un état incohérent. Cela en fait un peu difficile à utiliser.

  4. Le verrouillage n'est pas automatique (dans les langues que je connais), vous devez donc faire très attention à la mémoire (implicitement) partage.


0 commentaires

1
votes

Puisque la question est étiquetée avec 'Java', je suppose que vous connaissez Java, auquel cas il s'agit d'un excellent tutoriel d'introduction http://java.sun.com/docs/books/Tutorial/essential / Concurrence /


0 commentaires

1
votes

orm, bonne question à poser. Je pense que tous les programmeurs sérieux devraient en apprendre davantage sur les threads, car vous éventuellement envisageront au moins de les utiliser et que vous voulez vraiment être préparé quand cela se produit. Les bugs concurrency peuvent être incroyablement subtils et le meilleur moyen de les éviter est de savoir ce que les idiomes sont sûrs (-SH).

Je vous recommande vivement de prendre le temps de lire le livre programmation simultanée en Java: principes de conception et modèles par Doug Lea: http://gee.cs.oswego.edu/dl/cpj/ < / p>

Lea prend le temps non seulement pour vous apprendre aux concepts, mais également à vous montrer les moyens corrects et incorrects d'utiliser les primitives de programmation simultanées (en Java, mais également utile pour tout autre environnement utilisant un style de verrouillage / de signalisation partagée. concurrence). Surtout, il enseigne le respect de la difficulté de la programmation simultanée.

Je devrais ajouter que ce style de programmation simultanée est la seule approche la plus courante mais pas la seule approche. Il y a aussi un message qui passe, ce qui est plus sûr mais vous oblige à structurer votre algorithme différemment.


0 commentaires

1
votes

Étant donné que le poste d'origine est très large et aussi étiqueté avec C ++, je pense que les pointeurs suivants sont pertinents:

Anthony Williams, responsable de la bibliothèque de thread de Boost, travaille sur un livre appelé "C ++ Concurrence en action", une description de laquelle vous pouvez trouver ici . Le premier chapitre (introductif) est disponible gratuitement au formulaire PDF ici .

Aussi, Herb Sutter (connu, entre autres choses pour sa série "Exceptionnelle C ++") a écrit un livre à appeler "Concurrence effective", de nombreux articles sont disponibles sous la forme brune ici .


0 commentaires