2011-05-11 2 views
1

Je recherche des informations sur la programmation réseau Windows. Principalement comment obtenir un seul exécutable pour faire face à 1000 connexions.Performances Windows posix sockets

Nous utilisons select() FD_ISSET etc sur unix et cela fonctionne très rapidement. Sous Windows, ces API sont très pauvres. FD_SET est beaucoup plus lent mais même en travaillant autour de cela, Windows est beaucoup plus lent que HPUX.

Je suis à la recherche d'un appel d'API win32 que je peux utiliser à la place de l'appel select() qui ne nécessite pas beaucoup de CPU/temps. Actuellement, nous passons 50% du temps (et du CPU) dans select(), où, comme sur unix, le temps passé dans send() et recv(), ce qui est ce à quoi je m'attendais.

Merci Neil

Répondre

2

Vous cherchez probablement Windows I/O Completion Ports. Voici un article de SysInternals gars.

+0

Merci, ça ressemble exactement à ce dont j'ai besoin. La principale chose que je dois décider maintenant est de réimplémenter le serveur avec des ports d'achèvement d'E/S ou d'utiliser java (comme nous avons déjà 50% de nos serveurs exécutant java et 50% c programmes hérités) étant dit de résoudre un problème de performance Windows :) –

+0

Autres liens utiles - http://msdn.microsoft.com/en-us/library/aa365198.aspx - http://int64.org/2009/05/13/high -performance-io-on-windows –

1

Si vous êtes vraiment dans la programmation des sockets scalables, rien ne surpasserait les ports d'achèvement des E/S sous Windows. Cela dit, vous aurez probablement besoin d'une grande réécriture pour le modèle des ports de complétion.

Cependant, il est possible d'améliorer les performances même avec select()/FD_ISSET.

Voici comment cela peut se faire: dans Winsock2.h fd_set est défini comme un tableau de SOCKETs et un compteur d'éléments

typedef struct fd_set { 
    u_int fd_count;    /* how many are SET? */ 
    SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */ 
} fd_set; 

également dans Winsock2.h vous verrez que FD_SET ajoute une prise à la fin de ce tableau, et FD_ISSET effectue une recherche linéaire dans le tableau.

Maintenant, si vous modifiez des macros pour utiliser le tableau triée de SOCKETs, à savoir

  • FD_SET ajoute prises dans l'ordre de tri
  • FD_ISSET ne recherche binaire au lieu de linéaire

puis en fonction de la La taille du tableau FD_ISSET peut être grandement améliorée (alors que les performances de FD_SET se dégraderont quelque peu, mais nous supposons que FD_SET est rarement une opération).

Sous Unix, les performances de select() sont meilleures car FD_SET en tant que bitmap, FD_SET/FD_ISSET ne ferait que tester ou définir un bit. Sous Windows, cette technique ne serait pas applicable car le socket n'est pas un petit nombre de descripteurs de fichiers positifs, il s'agit d'un HANDLE et la valeur scalaire d'un handle peut être grande.

+0

J'ai utilisé ce type de 'correctif' pour obtenir des performances allant de 360 ​​à seulement 30 secondes, mais c'est quand même beaucoup plus lent que les HPUX de 1 ou 2 secondes. Il a enlevé beaucoup de n sections au carré du code. –

+0

Ouais, c'est certainement un klugde, et une bonne solution serait async io à la fin des ports.WSAPoll() (semblable à Unix poll(), disponible depuis Vista) peut être utile - même si je me souviens qu'il était plutôt lent quand il a été publié - plus lent que "optimisé" select() dans mes tests. Il est possible qu'il ait été amélioré depuis. –