Performances IPC: tuyau nommé vs socket


114

Tout le monde semble dire que les tubes nommés sont plus rapides que les sockets IPC. Combien plus rapides sont-ils? Je préférerais utiliser des sockets car ils peuvent faire une communication bidirectionnelle et sont très flexibles, mais je choisirai la vitesse plutôt que la flexibilité si elle est considérable.


10
Votre kilométrage variera. :) Créez un profil d'utilisation typique de votre application prévue et choisissez la meilleure des deux. Ensuite, profilez les canaux anonymes, les sockets d'autres domaines et familles, les sémaphores et la mémoire partagée ou les files d'attente de messages (SysV et POSIX), les signaux en temps réel avec un mot de données, ou autre. pipe(2)(euh,? mkfifo(3)) peut être le gagnant, mais vous ne le saurez pas avant d'essayer.
Pilcrow

2
Files d'attente de messages SysV FTW! Je ne sais pas s'ils sont rapides, j'ai juste un faible pour eux.
Tom Anderson

4
Qu'est-ce que la "vitesse" dans ce cas? Taux de transfert de données global? Ou latence (à quelle vitesse le premier octet arrive-t-il au récepteur)? Si vous voulez un transfert de données local rapide, il est difficile de battre la mémoire partagée. Si la latence est un problème, alors la question devient plus intéressante ...
Ian Ni-Lewis

Réponses:


64

Je vous suggérerais de commencer par la voie facile, en isolant soigneusement le mécanisme IPC afin que vous puissiez passer d'une prise à l'autre, mais je choisirais certainement la prise en premier. Vous devez vous assurer que les performances IPC posent problème avant de procéder à une optimisation préventive.

Et si vous rencontrez des problèmes à cause de la vitesse IPC, je pense que vous devriez envisager de passer à la mémoire partagée plutôt que de passer au canal.

Si vous voulez faire des tests de vitesse de transfert, vous devriez essayer socat , qui est un programme très polyvalent qui vous permet de créer presque n'importe quel type de tunnel.


48

Les meilleurs résultats que vous obtiendrez avec la solution de mémoire partagée .

Les canaux nommés ne sont que 16% meilleurs que les sockets TCP .

Les résultats sont obtenus avec l'analyse comparative IPC :

  • Système: Linux (Linux ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • Message: 128 octets
  • Nombre de messages: 1000000

Référence de tuyauterie:

Message size:       128
Message count:      1000000
Total duration:     27367.454 ms
Average duration:   27.319 us
Minimum duration:   5.888 us
Maximum duration:   15763.712 us
Standard deviation: 26.664 us
Message rate:       36539 msg/s

Benchmark FIFO (tubes nommés):

Message size:       128
Message count:      1000000
Total duration:     38100.093 ms
Average duration:   38.025 us
Minimum duration:   6.656 us
Maximum duration:   27415.040 us
Standard deviation: 91.614 us
Message rate:       26246 msg/s

Benchmark Message Queue:

Message size:       128
Message count:      1000000
Total duration:     14723.159 ms
Average duration:   14.675 us
Minimum duration:   3.840 us
Maximum duration:   17437.184 us
Standard deviation: 53.615 us
Message rate:       67920 msg/s

Benchmark de mémoire partagée:

Message size:       128
Message count:      1000000
Total duration:     261.650 ms
Average duration:   0.238 us
Minimum duration:   0.000 us
Maximum duration:   10092.032 us
Standard deviation: 22.095 us
Message rate:       3821893 msg/s

Benchmark des sockets TCP:

Message size:       128
Message count:      1000000
Total duration:     44477.257 ms
Average duration:   44.391 us
Minimum duration:   11.520 us
Maximum duration:   15863.296 us
Standard deviation: 44.905 us
Message rate:       22483 msg/s

Benchmark des sockets de domaine Unix:

Message size:       128
Message count:      1000000
Total duration:     24579.846 ms
Average duration:   24.531 us
Minimum duration:   2.560 us
Maximum duration:   15932.928 us
Standard deviation: 37.854 us
Message rate:       40683 msg/s

Référence ZeroMQ:

Message size:       128
Message count:      1000000
Total duration:     64872.327 ms
Average duration:   64.808 us
Minimum duration:   23.552 us
Maximum duration:   16443.392 us
Standard deviation: 133.483 us
Message rate:       15414 msg/s

1
Merci pour l'analyse comparative détaillée. Voulez-vous dire "multiprocessing.Queue" avec "Message Queue"?
ovunccetin

1
Message Queue est une file d'attente de messages système XSI ( man7.org/linux/man-pages/man0/sys_msg.h.0p.html )
chronoxor

34

Je vais être d'accord avec shodanex, il semble que vous essayez prématurément d'optimiser quelque chose qui n'est pas encore problématique. À moins que vous ne sachiez que les sockets vont être un goulot d'étranglement, je les utiliserais simplement.

Beaucoup de gens qui ne jurent que par des tuyaux nommés trouvent un peu d'économies (selon la façon dont tout le reste est écrit), mais se retrouvent avec du code qui passe plus de temps à bloquer une réponse IPC qu'à faire un travail utile. Bien sûr, les systèmes non bloquants y contribuent, mais ceux-ci peuvent être délicats. En passant des années à faire entrer l'ancien code dans l'ère moderne, je peux dire que l'accélération est presque nulle dans la majorité des cas que j'ai vus.

Si vous pensez vraiment que les sockets vont vous ralentir, sortez de la porte en utilisant la mémoire partagée en faisant très attention à la façon dont vous utilisez les verrous. Encore une fois, en réalité, vous pourriez trouver une petite accélération, mais notez que vous en gaspillez une partie en attendant des verrous d'exclusion mutuelle. Je ne vais pas préconiser un voyage en enfer futex (enfin, plus vraiment l' enfer en 2015, selon votre expérience).

Livre pour livre, les sockets sont (presque) toujours la meilleure solution pour l'espace utilisateur IPC sous un noyau monolithique .. et (généralement) la plus simple à déboguer et à maintenir.


2
peut-être qu'un jour dans un futur utopique lointain, nous aurons un noyau complètement nouveau, modulaire et moderne qui offre implicitement toutes les capacités (interprocessus et autres) que nous marchons actuellement sur du verre brisé pour accomplir ... mais bon ... on peut rêver
Gukki5

27

Gardez à l'esprit que sockets ne signifie pas nécessairement IP (et TCP ou UDP). Vous pouvez également utiliser des sockets UNIX (PF_UNIX), qui offrent une amélioration notable des performances par rapport à la connexion à 127.0.0.1


1
Et Windows?
Pacerier

1
@Pacerier Malheureusement, vous ne pouvez pas créer de sockets locaux sous Windows de la même manière que l'espace de noms abstrait sous UNIX. J'ai trouvé que les sockets PF_UNIX sont nettement plus rapides (> 10%) que la plupart des autres méthodes décrites sur cette page.
EntangledLoops

1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows , les sockets Unix sont désormais disponibles dans Windows 10.
eri0o le


11

Si vous n'avez pas besoin de vitesse, les prises sont la solution la plus simple!

Si vous recherchez la vitesse, la solution la plus rapide est la mémoire partagée, et non les canaux nommés.


8

Pour une communication bidirectionnelle avec des canaux nommés:

  • Si vous avez peu de processus, vous pouvez ouvrir deux canaux pour deux directions (processA2ProcessB et processB2ProcessA)
  • Si vous avez de nombreux processus, vous pouvez ouvrir des canaux d'entrée et de sortie pour chaque processus (processAin, processAout, processBin, processBout, processCin, processCout, etc.)
  • Ou vous pouvez devenir hybride comme toujours :)

Les tubes nommés sont assez faciles à mettre en œuvre.

Par exemple, j'ai implémenté un projet en C avec des tubes nommés, grâce à la communication basée sur les entrées-sorties de fichiers standart (fopen, fprintf, fscanf ...) c'était si simple et propre (si c'est aussi une considération).

Je les ai même codés avec java (je sérialisais et envoyais des objets dessus!)

Les tubes nommés présentent un inconvénient:

  • ils ne sont pas mis à l'échelle sur plusieurs ordinateurs comme les sockets car ils dépendent du système de fichiers (en supposant que le système de fichiers partagé n'est pas une option)

8

Un problème avec les sockets est qu'ils ne disposent pas d'un moyen de vider le tampon. Il y a quelque chose appelé l'algorithme Nagle qui collecte toutes les données et les vide après 40 ms. Donc, s'il s'agit de réactivité et non de bande passante, vous feriez peut-être mieux d'utiliser un tuyau.

Vous pouvez désactiver le Nagle avec l'option socket TCP_NODELAY mais la fin de lecture ne recevra jamais deux messages courts en un seul appel de lecture.

Alors testez-le, je me suis retrouvé avec rien de tout cela et j'ai implémenté des files d'attente basées sur la mémoire mappée avec pthread mutex et sémaphore dans la mémoire partagée, évitant ainsi beaucoup d'appels système du noyau (mais aujourd'hui ils ne sont plus très lents).


3
"Alors testez-le" <- des mots à vivre.
Koshinae

6

Les tuyaux et prises nommés ne sont pas fonctionnellement équivalents; les sockets offrent plus de fonctionnalités (elles sont bidirectionnelles, pour commencer).

Nous ne pouvons pas vous dire ce qui fonctionnera le mieux, mais je soupçonne fortement que cela n'a pas d'importance.

Les sockets de domaine Unix feront à peu près ce que les sockets tcp feront, mais uniquement sur la machine locale et avec (peut-être un peu) moins de temps système.

Si un socket Unix n'est pas assez rapide et que vous transférez beaucoup de données, pensez à utiliser la mémoire partagée entre votre client et votre serveur (ce qui est BEAUCOUP plus compliqué à configurer).

Unix et NT ont tous deux des "tubes nommés" mais ils sont totalement différents dans l'ensemble de fonctionnalités.


1
Eh bien, si vous ouvrez 2 tuyaux, vous obtenez également un comportement bidirectionnel.
Pacerier

4

Vous pouvez utiliser une solution légère comme ZeroMQ [ zmq / 0mq ]. Il est très facile à utiliser et considérablement plus rapide que les prises.


2
Vous aimerez peut-être, devinez Amit, la prochaine œuvre d'art de Martin SUSTRIK - compatible POSIX nanomsg. Quoi qu'il en soit, accueillez et profitez de cet endroit formidable et devenez un membre contributeur actif.
user3666197
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.