9
votes

Lorsque les messages deviennent plus gros, les télécommandes IPCChannel deviennent plus lentes

J'évalue diverses méthodes de communication interprocesses pour un couple de processus .NET 2.0 strong> résidant sur la même machine forte>. Naturellement, la télécommande .NET est un candidat et théoriquement la configuration la plus rapide doit être IPCChannel (Tipes nommées) + Binaryformatter.

Mes points de repère montrent vraiment que Remoting sur IPCChannel pourrait surtout plus vite que TCPChannel, mais IPCChannel montre une goutte raide Débit lorsque les messages deviennent plus gros (environ 30 Mo): p>

private byte[] _bytes = null;

public byte[] HelloWorld(long size)
{
    if (_bytes == null || _bytes.Length != size)
        _bytes = new byte[size];
    return _bytes;
}


8 commentaires

Juste une pensée, avez-vous confirmé qu'avec les charges utiles plus importantes, les messages ne sont pas mis en cache sur le disque quelque part? Voici la raison pour laquelle je demande - IIS 7 aboutis automatiquement de grandes demandes de disque pour éviter de consommer trop de RAM ... Je me demande si .NET ou Windows implémente un comportement similaire et lorsque la taille du message augmente, l'I / O cachée se produit. . Si ce n'est pas un disque I / O, ma prochaine hypothèse serait la taille du morceau du message.


@Tim: Je n'ai pas. En supposant que je trouve que cela a trait à I / O caché, est-ce que je peux réellement faire à ce sujet? par exemple. Reconfigure Remoting ou IPCChannel pour se comporter différemment?


@Yodan - Je ne sais pas comment vous réduiriez la mise en cache de disque caché, mais cela pourrait avoir quelque chose à voir avec la quantité de RAM est allouée au processus (ES) en question. Avez-vous examiné la consommation de ressources sur la machine lors de l'envoi de gros messages à plusieurs reprises? Même avec des fichiers très volumineux (j'ai essayé avec 500 Mo +) la manipulation pure du flux (comme le transfert de données d'un processus à un autre) entraîne une consommation très faible de la mémoire et aucun disque d'E / S. Par conséquent, si vous constatez des pointes de RAM / de disque (surtout si vous voyez des différences entre TCP et IPC), cela peut vous donner une indication de ce qui se passe.


@YODAN - Si vous essayez un message plus large (peut-être 100 Mo), la performance se dégrade de manière linéaire?


@Tim: avec 100 MB Messages - TCP: 112 MB / S, IPC: 18 Mo / s.


@YODAN - C'est une goutte de performance escarpée ... tout ce qui est remarquable avec la consommation de ressources sur la machine lorsque vous avez exécuté ce test? Aussi, y a-t-il une raison pour laquelle vous utilisez des prises de racélie par rapport à des prises brutes ( msdn.microsoft.com/en-us/library/system.net.sockets.socket. ASPX )? J'ai lu les liens que @Alois postés ci-dessous et je suis d'accord que le formateur crée probablement une partie des frais généraux (bien que je ne sache pas pourquoi il serait différent entre TCP et IPC).


@IM: Bien sûr, il y a une raison pour laquelle je préfère utiliser des sockets bruts - la télécommande est une solution complète RPC / IPC, les prises sont un moyen de transport. Je devrais réinventer quelques roues. En ce qui concerne le formidateur binaire - il est en effet beaucoup plus lent qu'il ne devrait l'être, mais n'est certainement pas la cause de la goutte de performance escarpée d'IPCChannel.


En outre, autrement que la CPU étant utilisé un peu plus avec le TCPChannel, je ne trouve aucune différence notable entre la consommation de ressources dans les deux cas.


3 Réponses :


1
votes

Pourquoi voulez-vous éviter la mémoire partagée? C'est le choix le plus évident pour déplacer de gros blobs.


1 commentaires

Comme il introduit une nouvelle couche de complications et de synchronisations (et de couplage fort), tandis que ces deux processus sont développés par deux sociétés distinctes. Déboguer ce sera sûrement un cauchemar. Je suppose que je ne veux tout simplement pas sortir des gros canons avant que je doive le faire.



1
votes

Le comportement "étrange" pour les grandes tailles de messages (30 Mo) est certainement orginée de la pression de GC. Au fait, BinaryFormatter devrait être le plus lent de toutes formes possibles. Datacontractformatter pourrait être beaucoup mieux ou une main écrite comme cette beauté http://codebetter.com/blogs/gregyoung/archive/2008/08/24/fast-serialization.aspx devrait être environ 16 fois plus rapide. Comment avez-vous mesuré le temps? Le processus d'envoi et de réception était-il le même? Je pense que 120 Mo / s Envoyer Recevoir sont assez bons pour .Net avec un collecteur à ordures très occupé. Vous devriez avoir un look a le compteur de performance de temps en% GC pour vérifier s'il est élevé. S'il est> 95%, vous devez utiliser la mémoire plus avec parcimonie. Comme les autres commentateurs ont déjà signalé des fichiers mappés de mémoire sont la voie à suivre si vous devez transmettre d'énormes quantités de données entre les processus. Il existe de nombreuses implémentations libres autour comme

http://www.codeproject.com/kb/recipes/memoryMappeReCarray.aspx < / a>

et

http://msdn.microsoft.com/en-us/library/ FF650497.aspx (Application hors ligne intelligente du client bloc a une dll qui contient un belle mise en œuvre).

le vôtre, Alois kraus


3 commentaires

Tout d'abord, merci de vos suggestions. Je vais regarder en eux. DatacontractFormatter n'est malheureusement pas une option (bloquée avec .NET 2.0). Lorsque j'ai mesuré le temps, j'ai utilisé deux processus distincts pour le serveur et le client.


Le processus client utilise environ 25% de CPU et dépense <1% de temps dans GC. Le processus de serveur dépense entre 10 et 80% de temps en GC, mais utilise seulement environ 5% de processeur. Ceci est vrai pour IPCChannel et TCPChannel, et donc, j'ai du mal à croire que cela provoque que IPCChannel devienne 4 fois plus lent lorsque la taille du message est de 30 Mo (comme TCPChannel ne souffre pas du même symptôme).


Si l'expéditeur a une utilisation faible de la CPU, il est possible que votre récepteur bloque la communication. Combien de cœurs votre machine a-t-elle? Si votre processus client consomme 25% sur une machine à noyau quadride, saturer une CPU est saturée.



1
votes

Un pistolet plus petit puis la mémoire partagée mais toujours assez puissante pour le travail serait des prises. Lors de l'exécution de la procédure distante, demandez-la de créer un Ecouter ING Socket sur un numéro de port fixe ou ad-hoc, connectez-le du client à celui-ci, utilisez NetworkStream pour écrire des données de un côté à un autre.

Cela fonctionnera comme un charme, je suis sûr.

Cet article devrait vous aider à démarrer.

Et, même si vous ne mentionnez rien de devoir avoir à faire des machines distinctes de serveur et de client, vous aurez toujours cette capacité, ce qui va disparaître si vous utilisez la mémoire partagée.


4 commentaires

Idée intéressante. Je suis capable de réaliser 230 Mo / s en invoquant une méthode par IPCChannel ou TCPChannel à distance et en passant les données binaires réelles via une prise distincte. Je devrai considérer cela - merci!


@Yodan - content de vous aider - je ne vais jamais envisager d'utiliser du savon pour passer un objet important de plusieurs mbs de taille - à première vue, cela sent le type d'odeur drôle.


@YODAN TAUBER - Vous souhaitez probablement aussi évaluer une conception similaire mais en utilisant un canal latéral de tuyau nommé au lieu de sockets pour les données binaires. Je suppose que cela serait encore plus rapide.


Qui a dit quoi que ce soit sur le savon? :)