Quelle est l'importance du multithreading dans l'industrie actuelle du logiciel? [fermé]

59

J'ai près de 3 ans d'expérience dans l'écriture d'applications Web en Java avec des frameworks MVC (comme struts). Je n’ai jamais écrit de code multithread jusqu’à présent, même si j’ai écrit du code pour les grandes chaînes de distribution.

Je reçois quelques questions sur le multithreading au cours des entretiens et j'y réponds généralement (principalement des questions simples). Cela m’amène à me demander quelle est l’importance du multithreading dans le scénario actuel du secteur.

utilisateur2434
la source
8
Vous ne l’avez peut-être pas fait explicitement, mais vous en avez certainement profité en coulisse.
Martin York le
1
Je travaille trop rarement avec du code multithread pour le travail, mais j'essaie de le lire / de pouvoir en discuter pendant une interview. Je ne voudrais pas travailler avec des codeurs qui n'ont pas de threads, ni avec des codeurs qui se moquent de savoir si d'autres codeurs obtiennent des threads.
Job le
1
Je l'utilise rarement dans le développement Web, mais je pense que c'est plus courant ailleurs. Par exemple, j'écrivais récemment une application Android et vous êtes rendu compte tenu d'utiliser multithreading si vous avez une activité de réseau.
jwegner
4
Ce n'est pas le multithreading qui compte, mais l'informatique parallèle. Si vous pensez que toutes les requêtes simples adressées à votre application Web figurent dans le fil ... vous devez fumer quelque chose.
user606723
1
La possibilité de "penser en dehors du fil" est très utile même pour la programmation en thread unique. Vous prenez beaucoup moins pour acquis et votre code est généralement plus robuste et réutilisable.
CorsiKa

Réponses:

92

C'est extrêmement important.

Le plus important est de comprendre que le multithreading n’est qu’un moyen de résoudre le problème de l’asynchronie. L’environnement technique dans lequel de nombreuses personnes écrivent maintenant des logiciels diffère de l’environnement de développement de logiciels historique (des applications monolithiques effectuant des calculs par lots) de deux manières principales:

  • Les machines à plusieurs noyaux sont maintenant courantes. Nous ne pouvons plus nous attendre à ce que les vitesses d'horloge ou les densités de transistors augmentent d'un ordre de grandeur à l'autre. Le prix du calcul continuera à baisser, mais il tombera à cause de beaucoup de parallélisme. Nous allons devoir trouver un moyen de tirer parti de ce pouvoir.

  • Les ordinateurs sont maintenant fortement interconnectés et les applications modernes doivent pouvoir extraire des informations riches à partir de diverses sources.

Du point de vue du calcul, ces deux facteurs se résument essentiellement à la même idée de base: les informations seront de plus en plus disponibles de manière asynchrone . Que les informations dont vous avez besoin soit calculée sur une autre puce de votre machine ou sur une puce à l'autre bout du monde n'a pas d'importance. Dans les deux cas, votre processeur est en train de graver des milliards de cycles à la seconde, attendant des informations, alors qu’il pourrait faire un travail utile.

Donc, ce qui compte maintenant et ce qui le sera encore plus à l'avenir, ce n'est pas le multithreading en soi, mais plutôt le traitement de l'asynchronisme . Le multithreading n’est qu’un moyen d’y parvenir - une méthode compliquée et sujette aux erreurs qui ne fera que se compliquer encore et encore davantage à mesure que les puces des modèles à mémoire faible deviennent plus largement utilisées.

Le défi des éditeurs d’outils est de proposer aux clients un moyen plus efficace que le multithreading de gérer l’infrastructure asynchrone qu’ils utiliseront à l’avenir.

Eric Lippert
la source
5
+1 pour une excellente réponse, elle mérite plus de crédit que ma modeste tentative.
Péter Török le
2
L'information sera de plus en plus disponible de manière asynchrone. Si ce n'est pas la vérité. . .
surfasb
2
concurrencyest plus important que le asynchronous comportement. Vous pouvez avoir un système asynchrone sans concurrence (plusieurs threads sur un même processeur) asynchronousn'est pas un substitut sémantique concurrency.
5
@Jarrod: L'asynchronisme maîtrisé est plus important que le simple fait d'apprivoiser la concurrence d' accès, précisément pour la raison que vous mentionnez: la simultanéité est une forme d'asynchronisme particulièrement difficile. La partie difficile de la concurrence n’est pas l’aspect «choses qui se passent en même temps» et, en fait, la concurrence n’est souvent que la concurrence simulée , par exemple le multitâche non coopératif par découpage temporel. La difficulté consiste à utiliser efficacement les ressources sans bloquer, suspendre, bloquer, et sans écrire à l’envers des programmes difficiles à raisonner localement.
Eric Lippert
"L'accès simultané n'est souvent que simulé, par exemple, le multitâche non coopératif via le découpage temporel": si j'ai bien compris, il s'agit toujours d'un accès concurrentiel (vrai), peut-être voulez-vous dire que ce n'est pas du parallélisme?
Giorgio
46

Cela devient de plus en plus important à mesure que les processeurs modernes ont de plus en plus de cœurs. Il y a dix ans, la plupart des ordinateurs existants ne disposaient que d'un seul processeur. Le multithreading n'était donc important que pour les applications serveur haut de gamme. De nos jours, même les ordinateurs portables de base ont des processeurs multicœurs. Dans quelques années, même les appareils mobiles ... Il faut donc de plus en plus de code pour utiliser les avantages potentiels de la simultanéité en termes de performances et pour fonctionner correctement dans un environnement multithread.

Péter Török
la source
3
+1: Plus important que jamais. N'oubliez pas également que dans une conception de système, vous pouvez également bénéficier des avantages du multithreading en partitionnant simplement le travail afin que davantage de processus le réalisent.
Scott C Wilson le
11
De nombreux appareils mobiles ont déjà des processeurs multicœurs!
Che Jami
3
Je dirais que le multi-threading est important depuis la création du premier système de partage du temps. Avoir plusieurs processeurs / cœurs ajoute simplement une nouvelle dimension d'efficacité à avoir plusieurs threads.
Jwernerny
Peut-être que les fils (surtout sur les appareils mobiles) sont une mauvaise idée. Le système d’exploitation devrait probablement gérer l’optimisation de l’utilisation des cœurs sans qu’un code utilisateur bogué ne tente de faire du threading. Il y a très peu d'applications qu'un utilisateur normal a accès à ce besoin ou pourrait en bénéficier pour des multitudes. Les seules exceptions sont (applications graphiques haut de gamme / outils de développement / modélisation météorologique / serveurs Web (et services associés)), toutes applications très haut de gamme.
Martin York
1
@ Tux-D, vous pouvez très bien avoir un jeu sur un appareil mobile qui utilise plus d’un noyau. Ce n'est pas quelque chose d'exceptionnel.
Whitequark
28

En général, le multi-threading est déjà très important et ne le deviendra que dans les prochaines années (comme l'a souligné Péter Török) - c'est ainsi que les processeurs évolueront dans un avenir prévisible (plus de cœurs au lieu de MHz supérieurs) .

Dans votre cas, cependant, vous semblez travailler principalement avec des applications Web. Les applications Web, de par leur nature, sont multi-threadées en raison de la manière dont votre serveur Web traite les demandes de chaque utilisateur (c.-à-d. En parallèle). Bien qu'il soit probablement important que vous compreniez la concurrence et la sécurité des threads (en particulier lorsque vous manipulez des caches et autres données partagées), je doute que vous rencontriez trop de situations dans lesquelles il est avantageux de multiplier le code de l'application Web en interne (par exemple, plusieurs travailleurs). threads par demande). En ce sens, je pense qu’être un expert en multi-threading n’est pas vraiment nécessaire pour un développeur web. C'est souvent demandé dans les interviews, parce que c'est un sujet assez délicat, et aussi parce que beaucoup d'interviewers ne font que chercher sur Google quelques questions 10 minutes avant que vous n'arriviez à y aller.

Daniel B
la source
+1 pour la note indiquant que l'affiche est un développeur Web et que la plupart des conteneurs de serveurs Web effectuent une quantité décente de multi-tâches pour vous. Cela n'élimine pas le besoin dans certains cas, mais 99% du temps, le code du contrôleur multithreading n'est pas la plus grande amélioration des performances pour un appel MVC.
Mufasa
19

Le multi-threading est un hareng rouge. Le multi-threading est un détail d'implémentation du problème réel qu'est la simultanéité . Tous les programmes threadés ne sont pas concurrents à cause de verrous ou non.

Les threads ne sont qu'un modèle et un seul modèle d'implémentation pour la mise en œuvre de concurrentprogrammes.

Par exemple, vous pouvez écrire un logiciel hautement évolutif et tolérant aux pannes sans utiliser de multi-threading dans des langues telles que Erlang.


la source
+1 bien que je pense toujours que Erlang est multi-threadé; la communauté vient de redéfinir le mot "fil" pour qu'il repose sur un état partagé mutable et se distingue ainsi.
Dan
1
La machine virtuelle Erlang utilise 1 thread par processeur par défaut, mais en tant que développeur Erlang, vous n'avez pas accès aux threads du système d'exploitation sous-jacent, mais uniquement aux processus légers fournis par la machine virtuelle Erlang.
10

Je reçois quelques questions sur le multithreading lors d'entretiens ...

Bien pour réussir les interviews, le multithreading peut être très important. En me citant , "lors des entretiens avec les candidats de notre équipe, je pose des questions de concurrence, non pas parce que ces compétences sont importantes dans notre projet ( mais pas du tout ), mais parce qu'elles facilitent en quelque sorte l'évaluation de la connaissance générale du langage que nous utilisons ..."

moucheron
la source
2
Avoir une idée du multithreading et de la programmation simultanée se traduit également par une approche défensive, ce qui peut être une très bonne chose. Si vous devez prendre en compte le fait que quelque chose de totalement indépendant de votre processus peut ou non préempter une seule instruction logique et s'exécuter au milieu de tout le reste, vous devez planifier cette possibilité. Les implémentations multithreads (par opposition aux autres formes de concurrence) signifient simplement que vous avez le fardeau supplémentaire de pouvoir faire quelque chose dans n'importe quel état qui n'est pas thread-local.
un CVn
6

Comprendre comment utiliser le threading pour améliorer les performances est une compétence essentielle dans l'environnement logiciel actuel, dans la plupart des industries et des applications.

Au minimum, comprendre les problèmes liés à la simultanéité devrait être une donnée.

La remarque évidente que toutes les applications ou tous les environnements ne pourront pas en tirer parti s’applique, par exemple dans de nombreux systèmes embarqués. Cependant, il semble que le processeur Atom (et autres) semble travailler pour changer cela (le multicœur léger commence à devenir plus courant).

Stephen
la source
4

On dirait que vous écrivez déjà du code multithread.

La plupart des applications Web Java peuvent gérer plusieurs demandes en même temps, en utilisant plusieurs threads.

Par conséquent, je dirais qu'il est important de connaître au moins les bases.

Tom Jefferys
la source
18
<nitpick> apparemment, il n'écrit pas de code multithread, mais uniquement du code (à un seul thread) exécuté dans un environnement multithread. </ nitpick>
Péter Török le
2

C'est toujours important dans les situations où vous en avez besoin, mais, comme beaucoup de choses en développement, c'est le bon outil pour le bon travail. Je suis resté 3 ans sans toucher au filetage, maintenant, pratiquement tout ce que je fais a des fondements. Avec les processeurs multicœurs, le besoin de threading reste important, mais toutes les raisons traditionnelles restent valables, vous voulez toujours des interfaces réactives et vous voulez toujours pouvoir gérer la synchronisation et passer à autre chose en même temps.

Nicholas Smith
la source
2

Réponse courte: très.

Réponse plus longue: les ordinateurs électroniques (à transistor) approchent rapidement des limites physiques de la technologie. Il devient de plus en plus difficile d'extraire plus d'horloges de chaque cœur tout en gérant la génération de chaleur et les effets quantiques des circuits microscopiques (les chemins de circuits sont déjà si proches les uns des autres sur les puces modernes qu'un effet appelé "sauter les pistes" d'un circuit à l'autre, sans avoir besoin des conditions appropriées pour un arc électrique traditionnel); par conséquent, pratiquement tous les fabricants de puces s’attachent plutôt à ce que chaque horloge puisse en faire plus, en mettant davantage d’unités d’exécution dans chaque processeur. Ensuite, au lieu que l'ordinateur ne fasse qu'une chose par horloge, il peut en faire 2, 4 ou même 8. Intel a "HyperThreading", qui divise fondamentalement un cœur de processeur en deux processeurs logiques (avec certaines limitations). Pratiquement tous les fabricants mettent au moins deux cœurs de processeur distincts dans une puce de processeur, et la norme de référence actuelle pour les processeurs de bureau est de quatre cœurs par puce. Huit est possible lorsque deux puces de processeur sont utilisées, il existe des cartes mères de serveur conçues pour les processeurs «quad quad-core» (16 EU plus HT en option), et la prochaine génération de CPU aura probablement six ou huit par puce.

Le résultat de tout cela est que, pour tirer pleinement parti de la façon dont les ordinateurs gagnent en puissance, vous devez être en mesure de lui permettre de "diviser pour régner" votre programme. Les langues gérées ont au moins un thread GC qui gère la gestion de la mémoire séparément de votre programme. Certains ont également des threads "de transition" qui gèrent l'interopérabilité COM / OLE (autant pour protéger le "bac à sable" géré que pour les performances). Au-delà de cela, vous devez toutefois commencer à réfléchir à la manière dont votre programme peut effectuer plusieurs tâches simultanément et à concevoir votre programme avec des fonctionnalités conçues pour permettre le traitement asynchrone de parties du programme. Les utilisateurs de Windows et de Windows s’attendront pratiquement à ce que votre programme exécute des tâches longues et compliquées dans des threads d’arrière-plan, qui maintiennent l'interface utilisateur de votre programme (qui s'exécute dans le fil principal du programme) "sensible" à la boucle de messages Windows. Les problèmes qui ont des solutions parallélisables (comme le tri) sont évidemment des candidats naturels, mais il existe un nombre fini de types de problèmes qui bénéficient de la parallélisation.

KeithS
la source
1

Juste un avertissement sur le multithreading: plus de threads ne signifie pas une meilleure efficacité. S'ils ne sont pas gérés correctement, ils peuvent ralentir le système. L'acteur de Scala améliore les threads Java et optimise l'utilisation du système (mentionnez-le en tant que développeur Java).

EDIT: Voici quelques points à garder à l’esprit sur les inconvénients du multithreading:

  • interférence de threads les uns avec les autres lors du partage de ressources matérielles
  • Les temps d'exécution d'un seul thread ne sont pas améliorés, mais peuvent être dégradés, même lorsqu'un seul thread est en cours d'exécution. Cela est dû à des fréquences plus faibles et / ou à des étages de pipeline supplémentaires nécessaires pour prendre en charge le matériel de commutation de threads.
  • La prise en charge matérielle du multithreading est plus visible pour les logiciels, nécessitant ainsi davantage de modifications à la fois des programmes d'application et des systèmes d'exploitation que le multitraitement.
  • Difficulté de gestion de la simultanéité.
  • Difficulté de test.

En outre, ce lien pourrait vous aider à peu près de la même manière.

c0da
la source
2
Cela ne semble pas répondre à la question du PO: - /
Péter Török le
Cependant, il donne une vue de haut niveau (la plupart) des threads. Une chose à considérer avant de plonger dans le multi-threading.
c0da
@ c0da Stack Exchange n'est pas un forum de discussion: les réponses doivent répondre directement à la question. Pouvez-vous développer votre réponse pour la ramener à ce que le demandeur cherche?
1

Cela m’amène à me demander quelle est l’importance du multithreading dans le scénario actuel du secteur.

Dans les domaines où les performances sont critiques et où les performances ne proviennent pas de codes tiers qui effectuent des tâches lourdes, mais des nôtres, j'aurais alors tendance à considérer les choses dans cet ordre d'importance du point de vue de la CPU (le GPU est un joker que j'ai gagné). n'entre pas dans):

  1. Efficacité de la mémoire (ex: localité de référence).
  2. Algorithmique
  3. Multithreading
  4. SIMD
  5. Autres optimisations (indications de prédiction de branche statique, par exemple)

Notez que cette liste n’est pas uniquement basée sur l’importance mais bien sur d’autres dynamiques telles que leur impact sur la maintenance, leur simplicité (si elles méritent d’être considérées plus à l’avance), leurs interactions avec d’autres sur la liste, etc.

Efficacité de la mémoire

La plupart pourraient être surpris de mon choix d'efficacité de la mémoire sur l'algorithmique. C'est parce que l'efficacité de la mémoire interagit avec les 4 autres éléments de cette liste, et parce que son examen est souvent beaucoup dans la catégorie "conception" plutôt que dans la catégorie "implémentation". Il y a certes un problème d'œuf ou de poule ici car comprendre l'efficacité de la mémoire nécessite souvent de prendre en compte les 4 éléments de la liste, tandis que les 4 autres éléments nécessitent également de prendre en compte l'efficacité de la mémoire. Pourtant, c'est au cœur de tout.

Par exemple, si nous avons besoin d’une structure de données offrant un accès séquentiel linéaire et des insertions constantes à l’arrière et rien d’autre pour les petits éléments, le choix naïf à rechercher ici serait une liste chaînée. Cela ne tient pas compte de l'efficacité de la mémoire. Lorsque nous considérons l'efficacité de la mémoire dans le mélange, nous finissons par choisir des structures plus contiguës dans ce scénario, telles que des structures développables basées sur des tableaux ou des nœuds plus contigus (par exemple, un stockant 128 éléments dans un nœud) liés entre eux, ou à tout le moins. une liste chaînée soutenue par un allocateur de pool. Celles-ci ont un avantage spectaculaire en dépit de la même complexité algorithmique. De même, nous choisissons souvent le tri rapide d'un tableau sur le tri par fusion malgré une complexité algorithmique inférieure simplement en raison de l'efficacité de la mémoire.

De même, nous ne pouvons pas avoir un multithreading efficace si nos modèles d'accès à la mémoire sont tellement granulaires et dispersés dans la nature que nous finissons par maximiser la quantité de faux partage lors du verrouillage aux niveaux les plus granulaires du code. L'efficacité de la mémoire multiplie donc l'efficacité du multithreading. C'est une condition préalable pour tirer le meilleur parti des threads.

Chaque élément situé au-dessus de la liste présente une interaction complexe avec les données, et le fait de se concentrer sur la façon dont les données sont représentées dépend en définitive de l'efficacité de la mémoire. Chacune de ces solutions peut être gênée par un moyen inapproprié de représenter ou d’accéder aux données.

Une autre efficacité de la mémoire de la raison est si important est qu'il peut appliquer tout au long de l' ensemble du code de base. Généralement, lorsque les gens imaginent que des inefficacités s’accumulent dans de petites parties du travail ici et là, c’est le signe qu’ils ont besoin d’un profileur. Pourtant, les champs à faible temps de latence ou ceux qui utilisent un matériel très limité trouveront, même après le profilage, des sessions n’indiquant pas de points chauds clairs (dispersés dans l’espace) dans une base de code qui est manifestement inefficace en termes d’allocation, de copie et de copie. accéder à la mémoire. En règle générale, il s'agit du seul moment où une base de code entière peut être affectée par des problèmes de performances pouvant conduire à un nouvel ensemble de normes appliquées dans toute la base de code, l'efficacité de la mémoire étant souvent au cœur de celle-ci.

Algorithmique

Celui-ci est à peu près une donnée, car le choix d'un algorithme de tri peut faire la différence entre une entrée massive prenant des mois à trier et des secondes à trier. L’impact le plus important réside dans le choix entre des algorithmes quadratiques ou cubiques vraiment sous-pairs et un algorithme linéarithmique, ou entre des algorithmes linéaires et logarithmiques ou constants, du moins jusqu’à ce que nous ayons environ 1 000 000 machines de base (auquel cas la mémoire). l'efficacité deviendrait encore plus importante).

Cependant, cela ne figure pas en haut de ma liste personnelle, car toute personne compétente dans son domaine saurait utiliser une structure d’accélération pour l’abattage frustum, par exemple: un arbre de base pour les recherches basées sur le préfixe est une affaire de bébé. En l'absence de ce type de connaissances de base du domaine dans lequel nous travaillons, l'efficacité algorithmique pourrait certainement atteindre le sommet, mais souvent, l'efficacité algorithmique est triviale.

Inventer de nouveaux algorithmes peut également s'avérer une nécessité dans certains domaines (par exemple, dans le traitement des maillages, j'ai dû inventer des centaines, soit qu'ils n'existaient pas auparavant, soit que les implémentations de fonctionnalités similaires dans d'autres produits étaient des secrets propriétaires, non publiés dans un article. ). Cependant, une fois que nous avons dépassé la partie consacrée à la résolution de problèmes et que nous avons trouvé le moyen d'obtenir les bons résultats, une fois que l'efficacité est devenue l'objectif recherché, le seul moyen de gagner réellement est de considérer la manière dont nous interagissons avec les données (mémoire). Sans comprendre l'efficacité de la mémoire, le nouvel algorithme peut devenir inutilement complexe avec de vains efforts pour le rendre plus rapide, alors que la seule chose dont il avait besoin était de prendre un peu plus en compte l'efficacité de la mémoire pour obtenir un algorithme plus simple et plus élégant.

Enfin, les algorithmes ont tendance à appartenir davantage à la catégorie "implémentation" qu'à l'efficacité de la mémoire. Ils sont souvent plus faciles à améliorer avec le recul, même avec un algorithme sous-optimal utilisé au départ. Par exemple, un algorithme de traitement d'image inférieur est souvent simplement implémenté à un emplacement local dans la base de code. Il peut être échangé contre un meilleur plus tard. Cependant, si tous les algorithmes de traitement d'image sont liés à une Pixelinterface ayant une représentation de mémoire sous-optimale, mais que le seul moyen de la corriger est de changer la façon dont plusieurs pixels sont représentés (et non un seul), nous sommes souvent SOL et devra réécrire complètement la base de code vers unImageinterface. Il en va de même pour le remplacement d'un algorithme de tri - il s'agit généralement d'un détail d'implémentation, tandis qu'une modification complète de la représentation sous-jacente des données en cours de tri ou de la manière dont elles sont transmises dans les messages peut nécessiter une nouvelle conception des interfaces.

Multithreading

Le multithreading est une tâche difficile du point de vue des performances car il s’agit d’une optimisation au niveau micro-informatique qui tient compte des caractéristiques matérielles, mais notre matériel évolue réellement dans cette direction. J'ai déjà des pairs qui ont 32 cœurs (j'en ai seulement 4).

Pourtant, la lecture à plusieurs pistes compte parmi les micro-optimisations les plus dangereuses probablement connues d'un professionnel si le but est utilisé pour accélérer les logiciels. La situation de concurrence critique est probablement le bogue le plus mortel possible, car elle est de nature tellement indéterministe (peut-être qu’une seule apparition tous les deux ou trois mois sur la machine d’un développeur à un moment des plus inconfortables en dehors d’un contexte de débogage, le cas échéant). On peut donc affirmer que la dégradation la plus négative en termes de maintenabilité et d’exactitude potentielle du code figure parmi celles-ci, d’autant plus que les bogues liés au multithreading peuvent facilement passer inaperçu lors des tests les plus minutieux.

Néanmoins, cela devient si important. Bien que le nombre de cœurs que nous avons actuellement ne soit pas toujours aussi efficace que l’efficacité de la mémoire (ce qui peut parfois rendre les choses cent fois plus rapide), nous en voyons de plus en plus. Bien sûr, même avec des machines à 100 cœurs, je mettrais toujours l’efficacité de la mémoire en tête de liste, car l’efficacité des threads est généralement impossible sans elle. Un programme peut utiliser une centaine de threads sur une telle machine tout en restant lent, sans une représentation efficace de la mémoire et des modèles d'accès (qui sont liés aux modèles de verrouillage).

SIMD

SIMD est également un peu gênant puisque les registres s’élargissent, avec des plans pour l’élargir. À l'origine, nous avons vu des registres MMX 64 bits suivis de registres XMM 128 bits capables de 4 opérations SPFP en parallèle. Nous voyons maintenant des registres YMM 256 bits capables de 8 en parallèle. Et il y a déjà des plans en place pour des registres de 512 bits qui permettraient 16 en parallèle.

Ceux-ci interagiraient et se multiplieraient avec l'efficacité du multithreading. Cependant, SIMD peut dégrader la maintenabilité tout autant que le multithreading. Même si les bogues qui leur sont associés ne sont pas nécessairement aussi difficiles à reproduire et à corriger qu'un blocage ou une situation critique, la portabilité est délicate, et il est essentiel de s'assurer que le code peut être exécuté sur la machine de tout le monde (et en utilisant les instructions appropriées en fonction de leurs capacités matérielles). gênant.

Une autre chose est que bien que les compilateurs ne battent généralement pas le code SIMD écrit avec brio, ils battent facilement les tentatives naïves. Ils pourraient s’améliorer à un point tel que nous n’avons plus à le faire manuellement, ou du moins que nous ne devenions pas assez manuels pour écrire des codes intrinsèques ou des assemblages simples (peut-être juste un peu de guidage humain).

Encore une fois cependant, sans une disposition de mémoire efficace pour le traitement vectorisé, SIMD est inutile. Nous finirons par charger un seul champ scalaire dans un registre large uniquement pour y effectuer une opération. Au cœur de tous ces éléments, il y a une dépendance à la disposition de la mémoire pour être vraiment efficace.

Autres optimisations

Celles-ci sont souvent ce que je suggérerais de commencer à appeler «micro» de nos jours si le mot suggère non seulement d’aller au-delà de l’algorithme, mais également d’apporter des modifications qui ont un impact minime sur les performances.

Tenter d'optimiser la prédiction de branche nécessite souvent une modification de l'algorithme ou de l'efficacité de la mémoire, par exemple, si cela n'est tenté que par des astuces et un réarrangement du code pour la prédiction statique, cela ne sert qu'à améliorer la première exécution de ce code, ce qui rend les effets douteux. pas souvent carrément négligeable.

Retour à Multithreading pour la performance

Quoi qu'il en soit, quelle est l'importance du multithreading dans un contexte de performance? Sur ma machine à 4 cœurs, elle peut idéalement être 5 fois plus rapide (ce que je peux obtenir avec l'hyperthreading). Ce serait beaucoup plus important pour mon collègue qui a 32 cœurs. Et cela deviendra de plus en plus important dans les années à venir.

C'est donc très important. Mais il est inutile de simplement lancer un tas de discussions sur le problème si l'efficacité de la mémoire n'est pas là pour permettre l'utilisation de verrous avec parcimonie, pour réduire le faux partage, etc.

Multithreading en dehors de la performance

Le multithreading ne concerne pas toujours la simple performance au sens de débit simple. Parfois, il est utilisé pour équilibrer une charge, même au coût possible du débit, afin d'améliorer la réactivité de l'utilisateur, ou pour permettre à l'utilisateur de faire plus de tâches multiples sans attendre la fin de l'opération (ex: continuer à naviguer pendant le téléchargement d'un fichier).

Dans ces cas, je suggérerais que le multithreading monte encore plus haut (peut-être même au-dessus de l'efficacité de la mémoire), puisqu'il s'agit alors d'une conception utilisateur plutôt que de tirer le meilleur parti du matériel. Cela va souvent dominer les conceptions d'interface et la façon dont nous structurons l'ensemble de notre base de code dans de tels scénarios.

Lorsque nous ne parallélisons pas simplement une boucle étroite en accédant à une structure de données volumineuse, le multithreading passe dans la catégorie des "concepteurs" vraiment extrêmes, et le design l'emporte toujours sur la mise en oeuvre.

Donc, dans ces cas, je dirais que considérer le multithreading dès le départ est absolument essentiel, même plus que la représentation en mémoire et l’accès.


la source
0

La programmation simultanée et parallèle est ce qui devient important. Les threads ne sont qu'un modèle de programmation permettant de faire plusieurs choses à la fois (et non en pseudo-parallèle comme avant la montée en puissance des processeurs multicœurs). Le multi-threading est (à mon humble avis) critiqué pour sa complexité et son dangerosité car les threads partagent de nombreuses ressources et il incombe au programmeur de les faire coopérer. Sinon, vous vous retrouvez avec des blocages difficiles à résoudre.

Sakis
la source
0

Étant donné que nous pouvons avoir besoin de contacter de nombreuses applications externes, il peut y avoir un processus d'arrière-plan qui nécessite une interaction plus longue du système externe et où l'utilisateur final ne peut attendre que le processus soit terminé. le multithreading est donc important ..

nous utilisons dans notre application, nous essayons d'abord de contacter le système externe s'il est en panne, puis nous sauvegardons la demande dans la base de données et couvrons un fil pour terminer le processus en arrière-plan. Peut également être requis dans les opérations par lots.

TPReddy
la source
0

Historiquement, les gens devaient se battre en faisant de la programmation multithread à la main. Ils devaient travailler directement avec tous les composants centraux (threads, sémaphores, mutexes, verrous, etc.).

Tous ces efforts ont abouti à des applications pouvant évoluer en ajoutant des processeurs supplémentaires à un seul système. Cette évolutivité verticale est limitée par "quel est le plus gros serveur que je peux acheter".

Aujourd'hui, je vois un changement dans l'utilisation de plusieurs frameworks et de différents modèles de conception pour la conception de logiciels. MapReduce est un modèle de ce type axé sur le traitement par lots.

L'objectif est la mise à l'échelle horizontale. Ajouter plus de serveurs standard au lieu d’acheter des serveurs plus gros.

Cela dit, il reste que la compréhension de la programmation multithread est très importante. J'ai été dans une situation où une personne a créé une situation de concurrence critique et je ne savais même pas ce qu'elle était jusqu'à ce que nous remarquions des erreurs étranges lors des tests.

Niels Basjes
la source
-1

Ma machine a 8 noyaux. Dans le Gestionnaire des tâches, j'ai 60 processus en cours d'exécution. Certains, comme VS, utilisent jusqu'à 98 threads. Outlook utilise 26. Je m'attends à ce que ma mémoire soit principalement utilisée par les piles allouées à chacun de ces threads inactifs.

J'attends personnellement que l'ordinateur à 300 cœurs sorte pour ne pas avoir à attendre qu'Outlook réponde. Bien entendu, Outlook utilisera alors 301 threads.

Le multi-threading importe uniquement si vous construisez des systèmes qui seront le seul processus important sur l'ordinateur à un moment donné (par exemple, des moteurs de calcul). Les applications de bureau feraient probablement l'utilisateur une faveur en n'utilisant jusqu'à chaque noyau disponible. Les applications Web utilisant le modèle demande / réponse sont intrinsèquement multi-threadées.

Cela compte pour les concepteurs de structures et de langages, ainsi que pour les programmeurs de systèmes dorsaux - moins pour les constructeurs d'applications. Comprendre certains concepts de base, tels que le verrouillage et l'écriture de code async, en vaut probablement la peine.

Paul Stovell
la source
Je vais souvent frapper quelque chose sur un fil de fond tel qu'un long chargement de base de données, mais c'est très rare que je sois confronté à des conditions de course ou à des verrous, etc. (en fait probablement jamais)
Aran Mulholland le