Bonjour,
J'ai un imx6 dl qui a donc 2 coeur j'ai développé jusque là une application un processus avec plusieurs thread. Ce développement n'est pas terminé. Je dois maintenant ajouter une grosse procédure de calcul. Je me suis dit je divise mon application en deux partie une partie sur un coeurs (ihm, communication,…) et sur un autre coeur (acquisition et calcul).
Dans un premier temps je me suis dit je cree deux processus un pour chaque coeur et j'utilise les fonctions sched_setaffinity. Mais j'ai vu aussi qu'il existait la même chose au niveau thread pthread_attr_setaffinity_np.
Donc je me pose la question dois je abandonner mon idée de deux process et continuer avec un seul process et repartir mes différents threads sur les deux coeur.
Donc j'aimerai avoir votre avis. Certainement personne me dise qu'utiliser un système multithread sur un multi core c'est lourd.
Donc j'ouvre un débat ou peut être pas est ce que c'est mieux d'utiliser dans mon cas un système multi thread sur du multi coeur ou du multi process sur du multi coeur.
Merci d'avance pour vos réponses.
# Commentaire supprimé
Posté par Anonyme . Évalué à 4.
Ce commentaire a été supprimé par l’équipe de modération.
# Besoin de tuning manuel ?
Posté par lolop (site web personnel) . Évalué à 2. Dernière modification le 24 février 2016 à 14:14.
Salut,
as-tu besoin de tuning manuel sur un réglage d'affinité entre les threads et les processeurs?
Régler éventuellement les priorités des threads et laisser faire le scheduler ne suffit-il pas?
Sinon, pour le choix process vs threads, je rejoins Francesco: as-tu des contraintes particulières? (perso, sauf contraintes d'isolation - ou d'affinité de cache mémoire, ce qui peut avoir un sens pour des calculs - je partirais sur du multithread)
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: Besoin de tuning manuel ?
Posté par benja . Évalué à 2.
En rejoignant Francesco et lolop, et en tentant de synthétiser voire de complèter :
Thread:
- communication simplifiée: i.e. un seul espace de mémoire partagé, attention aux problème de synchronisation à ces données (mutex) et de live/dead-lock.
- pas d'isolation en cas de plantages.
- nécessite d'utiliser des bibliothèque thread-safe, sauf si leur utilisation est confinée dans un seul thread (et encore… cf. genre perror).
- de manière générale, toute resource/fonctionnalité qui est associée à un processus est partagée entre ses threads : file descriptor, mémoire et autres mappings, privilèges et permissions, signaux, etc. Parfois il y a moyen d'utiliser une API par thread (cf. comme ton affinity), parfois non. Dans tous les cas, il faudra bien faire attention aux petites notes dans les pages man car souvent il y a certaines substilités ou interactions (par exemple, dans quelles conditions et quel thread reçoit le signal lorsqu'un fork d'un autre thread se termine (SIGCHLD) ? question non-triviale… :p).
- tant tous les cas, ce n'est pas plus lourd qu'utiliser des processus, ce serait même un peu plus lèger: si ce n'est au niveau de la mémoire kernel au moins au niveau du travail nécesaire à la création d'un nouveau thread. Dans ton cas (création à l'origine, nombre très réduit), c'est insignifiant. Amha on t'as dit ça dans le contexte d'un serveur web ou applicatif qui démarre un thread pour chaque nouvelle requête par opposition à un style de programmation évenementiel (qui n'a pas besoin de créer des nouvelles resources "lourdes"—thread, processus—pour s'accomoder d'une charge grandissante). Après tu as des archi hybrides async + thread-poll qui théoriquement peuvent-être très efficaces… Mais bon la on entre dans le domaine de l'overkill.
- possibilité d''utilisation d'un alogrithme paralellisable, à grand frais de complexité d'implémentation.
Processus:
- "force" un style de communication par message, ce qui en soit peut être un avantage et peut simplifier le raisonnement afin d'éviter les live-lock.
- permet aussi de partager une zone mémoire, certes avec un peu plus de travail: via mmap/shm. Pour faire de l'ipc (p.e. pour synchroniser l'accès), tu as aussi shm, les sémaphore et les ipc type sysV, et probablement d'autres trucs linux only
- plus robuste en cas de plantage mais nécessite alors un système de baby-sitting et de rendez-vous (qui peuvent être très simple à mettre en oeuvre, néanmoins cela reste à faire).
Une autre possibilité c'est l'utilisation de la programmation asynchrone avec boucle d'évènement et la partie "calcul" qui travaille de manière itérative sur des petis morceaux… Certes, ton programme n'exploite a lui seul plus les deux coeurs, mais le coeur inutilisé peut travailler pour le kernel, le pilote ou le processus de capture. Bref il faut savoir où est la charge avant de chercher à vouloir l'optimiser. Que te donne un "top" pendant la capture ? Normalement, la capture en tant que soit (
read()
) ne devrait pas prendre du temps cpu "user" à ton programme.grosso-modo:
while(ev=lastevent()) {
switch(ev) { case read_done: lire données suivante; case write_done: écrire données suivante; case default: itération calcul;} si calcul fini alors attendre le prochain évèvement, sinon vérifier sans attendre.
Bref selon moi la programmation évènementielle est la plus simple et la plus fiable, sans overhead du à la synchronisation; suit ensuite en terme de fiabilité la division en processus et je ne conseillerais les threads qu'en derniers recours. Par contre, ceux-ci sont indispensables si ton algorithme de calcul est "paralellisable", ce qui, sans vouloir te dénigrer, n'est à priori pas le cas car cela demande un niveau de compétance qui ferait que tu ne te poserais sûrement pas ici en premier lieu ;-)
# contraintes et requis
Posté par moi1392 . Évalué à 2.
Je dirais que cela dépends surtout de ton cahier des charges.
Pour faire court, le mutli-thread est plus leger d'un point de vue ressources système (un seul descripteur de processus, le même contexte de mémoire), et si tu as beaucoup de données à partager, tout est dans le même espace mémoire.
L'avantage du multi-process est justement que ton espace mémoire est distinct, donc un soucis (corruption mémoire, crash, faille de sécurité) dans un de tes processus n'impacte pas le second, et si tu peux facilement le relancer, tu ne perds pas le travail en cours dans le second. Après, la synchro est plus compliquée à mettre en place, et si tu as de gros volumes de données à partager, tu devras certainement utiliser un espace de mémoire partagé qu'il faudra aussi gérer.
# merci pour toutes ces info
Posté par yodalesage . Évalué à 1.
Merci à vous tous pour toutes ces info très utiles. Nous avons finalement opter pour du multi thread d'autant que nous portons une appli d'un os temps réel appelé lepton vers linux.
Merci à tous.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.