• [^] # Re: Besoin de tuning manuel ?

    Posté par . En réponse au message système multi thread vs multi process dans un système multi core. É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 ;-)