Toon posts:

[Win32/C++] Winsock perfomance slecht?

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hi,

heb ik een probleem (niet echt een probleem, maar wel een grens waar ik tegenaanloop en niet kan verklaren) :'(

Ik heb met winsock een client en server geschreven en nu ben ik een beetje aan het testen hoe snel die zijn. Ik krijg het echter niet voor elkaar om meer dan 64 messages (van +-128 byte) per seconde te versturen. :?

Het is voor een real-time-app, dus hoe sneller, hoe beter, en ik vraag me af waar deze grens zit ingebakken?

  • bigben04
  • Registratie: December 2001
  • Laatst online: 05-08 22:33
Test je dat met zowel client als server op dezelfde PC of over een netwerk? Ik kan hier in een hele simpele test met VB tussen een client en server op m'n localhost 6400 messages van 120 bytes versturen in ongeveer een seconde.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 18:33
Als je een echte real-time app wilt hebben moet je geen gebruik maken van TCP/IP en al helemaal niet van Windows.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 09 oktober 2003 @ 03:41:
Ik heb met winsock een client en server geschreven en nu ben ik een beetje aan het testen hoe snel die zijn. Ik krijg het echter niet voor elkaar om meer dan 64 messages (van +-128 byte) per seconde te versturen. :?
Dit is onzinnig langzaam. Licht inderdaad je testopstelling en/of code eens wat toe?

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
farlane schreef op 09 October 2003 @ 09:24:
Als je een echte real-time app wilt hebben moet je geen gebruik maken van TCP/IP en al helemaal niet van Windows.
Het is geen real-time app. Voor een real-time app geldt namelijk niet dat sneller=beter, het criterium is daar op tijd=goed. ALs je de waarde van een antwoord uitzet tegen de tijd krijg je dus zoiets:
code:
1
2
3
4
5
6
|********
|        * 
|        *
|        *
|        *************
+--------------------- t->

in plaats van
code:
1
2
3
4
5
6
7
8
|*
| * 
|  * 
|   ** 
|     ** 
|      *************
|
+--------------------- t->

In het laatste (niet real-time) geval zie je dat sneller=beter.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 18:33
MSalters schreef op 09 oktober 2003 @ 12:45:
Het is geen real-time app. Voor een real-time app geldt namelijk niet dat sneller=beter, het criterium is daar op tijd=goed.
Daar ben ik me van bewust, maar aangezien zowel Windows als TCP/IP je niet kunnen garanderen dat 'op tijd' uberhaupt kan optreden is real-time in die betekenis niet op zijn plek hier.

Is er trouwens een goed woord om een verschil aan te geven tussen deze real-time en de real-time die de TS waarschijnlijk bedoelde. ( Als in 'hoe sneller hoe beter' :) ) ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-08 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 09 October 2003 @ 03:41:
Ik heb met winsock een client en server geschreven en nu ben ik een beetje aan het testen hoe snel die zijn. Ik krijg het echter niet voor elkaar om meer dan 64 messages (van +-128 byte) per seconde te versturen. :?
Hoe meet je die snelheid?
En kun je eens wat code posten?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 17:14
farlane schreef op 09 October 2003 @ 13:27:
[...]
Daar ben ik me van bewust, maar aangezien zowel Windows als TCP/IP je niet kunnen garanderen dat 'op tijd' uberhaupt kan optreden is real-time in die betekenis niet op zijn plek hier.

Is er trouwens een goed woord om een verschil aan te geven tussen deze real-time en de real-time die de TS waarschijnlijk bedoelde. ( Als in 'hoe sneller hoe beter' :) ) ?
"misbruik" :)
ALs je bedoelde, hoe heet het gedrag wat de TS wil, dan is dat "interactief". De enige reden dat het snel moet is dat een gebruiker er op zit te wachten. Geen enkele tijd is te laat, maar eerder=beter. Dat is precies waar TCP/IP goed voor is. Het derde alternatief is "batch", wat zoveel betekent als "elke tijd is goed, stel maar uit tot je een geschikt moment hebt"

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Heb je misschien last van TCP's Nagle Algorithme? Juist bij interactieve communicatie tussen client en server kan dit de latency per transactie enorm doen toenemen.

Het is mogelijk op een socket om Nagle uit te zetten (met setsocketopt() uit m'n hoofd)

  • Soultaker
  • Registratie: September 2000
  • Nu online
Volgens mij is nog nergens uit gebleken dat het inderdaad om TCP ging; ik zou bij packets eerder aan andere protocollen denken. Misschien kan de TS die verwarring even uit de wereld helpen? Dan kan er ook wat specifieker advies gegeven worden.
Verwijderd schreef op 09 October 2003 @ 23:09:
Heb je misschien last van TCP's Nagle Algorithme? Juist bij interactieve communicatie tussen client en server kan dit de latency per transactie enorm doen toenemen.
Alleen als je zo weinig gegevens verstuurd dat je nooit een packet vol krijgt; als je je packet eenmaal hebt gevuld, wordt 'ie (in principe) verstuurd, Nagle of niet.
Het is mogelijk op een socket om Nagle uit te zetten (met setsocketopt() uit m'n hoofd)
TCP_NODELAY, denk ik.

[ Voor 3% gewijzigd door Soultaker op 09-10-2003 23:23 ]


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 18:33
Wat krijg je voor een meldingen dan eigenlijk ? WSA_WOULDBLOCK ?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

Soultaker schreef op 09 October 2003 @ 23:22:
Volgens mij is nog nergens uit gebleken dat het inderdaad om TCP ging; ik zou bij packets eerder aan andere protocollen denken.
De TS heeft het over winsock grote kans dat het een eigen packetbased protocol over TCP is...maar inderdaad het hoeft niet.
Alleen als je zo weinig gegevens verstuurd dat je nooit een packet vol krijgt; als je je packet eenmaal hebt gevuld, wordt 'ie (in principe) verstuurd, Nagle of niet.
een vol TCP segment moet 64KB zijn (toch?)in dit geval zijn de segmenten niet vol en moet de TCP stack wachten op de ACK van de peer (of max 200 milli sec) voordat weer verzonden mag worden. Aangezien de peer de ACK het liefst will piggybacken zie je vaak dat de ACK vrij lang op zich laat wachten. Dit heeft een lange latency tot gevolg.

[ Voor 9% gewijzigd door Verwijderd op 09-10-2003 23:43 ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Soultaker schreef op 09 October 2003 @ 23:22:
Volgens mij is nog nergens uit gebleken dat het inderdaad om TCP ging; ik zou bij packets eerder aan andere protocollen denken. Misschien kan de TS die verwarring even uit de wereld helpen? Dan kan er ook wat specifieker advies gegeven worden.
We weten zelfs nog niet of het localhost is of naar een server in Japan of naar een server drie meter verderop door een netwerkkabel met 20 breuken... :X

Wellicht dat we op iets meer info moeten wachten voordat we daarover verder gaan speculeren ;)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 21-08 12:02

.oisyn

Moderator Devschuur®

Demotivational Speaker

lange latency != lage snelheid. Als ie gewoon veel data verstuurd dan moet er ook veel aankomen. Dat laatste pakketje kan idd wat op zich laten wachten, maar ook maar maximaal een bepaalde tijd. En als hij gewoon continu stuurt dan zou het nagle algorithm dus niet eens uit moeten maken, aangezien de data zich blijft ophopen en dus steeds verstuurd wordt

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op 09 oktober 2003 @ 23:43:
lange latency != lage snelheid. Als ie gewoon veel data verstuurd dan moet er ook veel aankomen. Dat laatste pakketje kan idd wat op zich laten wachten, maar ook maar maximaal een bepaalde tijd. En als hij gewoon continu stuurt dan zou het nagle algorithm dus niet eens uit moeten maken, aangezien de data zich blijft ophopen en dus steeds verstuurd wordt
Niet per definitie. Maar....stel je het volgende scenario voor: Een host (client) stuurt een niet vol TCP segment naar een andere host (server). Vervolgens MOET (de TCP stack op) de client wachten met verzenden totdat de (TCP stack op de) server de TCP ACK heeft terug gestuurt. Deze ACK komt pas na
1) gemiddeld 100 ms ---OF---
2) Als de server het antwoord (van application level protocol) terug stuurt

Zo doende zie je een lange latency per transactie. Als nu blijkt dat de client middels stop-and-wait (of klein window) met de server praat dan wordt het traag. Als er van application level windowing gebruikt wordt gemaakt dan kan het het performance verlies beperkt worden de window size zal dan bepalend zijn voor de mate waar mee.

[ Voor 16% gewijzigd door Verwijderd op 10-10-2003 00:02 ]


Verwijderd

Topicstarter
Ok. sorry voor :

* de wat trage reactie, maar ik zit in Nieuw Zeeland, en de tijd loopt daar net iets anders
* het vern**ken van de layout

clientside:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    //SEND 1000 coordinate structs ----------------------------------
    while (count++ < total)
    {
        buffer[0] = CAMERA_COORDINATES_PACKET;
        * (Body2d *)&buffer[1] = b;
        try 
        {// Send the string to the echo server
            sock.send(buffer, bodysize);
            //cout << "res: " << res << "\n";
            memset(szResult,0,sizeof(szResult));
            res = sock.recv(szResult, sizeof(szResult)-1);
            if (res != SOCKET_ERROR)
            {
                if (res!=0)
                {
                    printf("The server said (%d): %s ", res, szResult);
                }
                res = WSAGetLastError();
            }

        }
        catch (SocketException &e)
        {
            cout << "exception\n";
        }
    }


serverside:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    s = select(nfds,&input_set,NULL,&exc_set,&timeout); // The Actual Select Function sees if data coming in and stores it in s
    
    if (s > 0) // Is there data coming in?
    {
        for (int i=0; i<MAX_CONNECTIONS; i++)       
        {
            if (clients[i].inUse)
            {
                if (FD_ISSET(clients[i].socket, &input_set)) // Actual Data coming through?
                {
                // Get whatever message the client sending, and carry out appropriate response
                    int res = clients[i].getMessage();
                    if ((res == SOCKET_ERROR) || (res == 0))
                        disconnect(clients[i]);
                }
            }
        }
    }


Waarbij getMessage() ongeveer er zo uit ziet:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int ClientHandler::getMessage()
{
    // Recieve The Data and Put into a Buffer Until we know what it is.
    char buffer[MAX_MSG_LENGTH];
    memset(buffer,0, MAX_MSG_LENGTH);
    int res = recv(socket,buffer,MAX_MSG_LENGTH,0);
    
    if (res == SOCKET_ERROR || res==0) 
    {
        return res;
    }
    if (strlen(buffer) == 0)
        return 1;
    /*
    else 
        printf("Message from %s: %s", ip.c_str(),buffer);*/

         if (clientType == UNKNOWN_CLIENT) {if (!parseHello(buffer, res)) return 0;} 
    else if (clientType == CAMERA_CLIENT)  parseCameraMsg(buffer, res);
    else if (clientType == DISPLAY_CLIENT) parseDisplayMsg(buffer, res);
    else if (clientType == ECHO_CLIENT) parseEchoMsg(buffer, res);
    else
    {
        //we should never get here!
        return 0;
    }
    return res;
}


extra toelichting:

Er kunnen camera-clients inloggen bij de server en hun informatie (een set van 2d punten) opsturen, de server stuurt een ok-berichtje terug

Er kunnen ook display clients inloggen, die sturen een REQ en krijgen een set 3D punten terug

De server berekent de 3d locatie van de door de 2+ camera's aangeleverde punten

Ik voer deze test eerst lokaal uit (alles op 1 PC) en daarna met een andere PC via een switch, maar het maakt geen verschil in tijd. Ik vermoed dus een restrictie in de drivers/hardware/winsock implementatie?

nog meer info:

Ik heb ook geprobeert gewoon niks terug te sturen vanuit de server naar de client. In dat geval kan ik de messages sneller versturen (+- 256 per seconde) maar dan komen ze niet allemaal aan (? raar ja inderdaad)

De toepassing moet "real-time" zijn -> als er een verandering in de camera-kant plaatsvind, moet dat binnen +- 10 ms aan de beeldkant bekend zijn, zodat er geen lag optreed (dus net zo snel als een TFT refresh rate zonder ghosting effect :-))

[ Voor 30% gewijzigd door Verwijderd op 10-10-2003 06:51 ]


Verwijderd

Topicstarter
Mzz. uiteindelijk toch niet veel met de Winsock te maken. Ik had ergens sleep(1) in de code staan ind e veronderstelling dat dat maar 1 ms duurt. niet dus :(, het duurt precies 1/64 seconde.

Verwijderd

lol?

en hoe snel is het nu dus?

Verwijderd

Topicstarter
1560 messages per second, dus das meer dan genoeg =)

  • Olaf van der Spek
  • Registratie: September 2000
  • Niet online
Verwijderd schreef op 09 October 2003 @ 23:51:
Niet per definitie. Maar....stel je het volgende scenario voor: Een host (client) stuurt een niet vol TCP segment naar een andere host (server). Vervolgens MOET (de TCP stack op) de client wachten met verzenden totdat de (TCP stack op de) server de TCP ACK heeft terug gestuurt. Deze ACK komt pas na
1) gemiddeld 100 ms ---OF---
2) Als de server het antwoord (van application level protocol) terug stuurt
Volgens mij is dat toch niet correct. Niet-volle segments zijn niet erg, niet-volle packets wel. De client hoeft alleen te wachten als de buffer op de server vol zit, anders zou het betekenen dat er nooit meer dan een packet 'in-flight' kan zijn.
C++:
1
2
3
4
5
6
7
8
          if (res != SOCKET_ERROR) 
            { 
                if (res!=0) 
                { 
                    printf("The server said (%d): %s ", res, szResult); 
                } 
                res = WSAGetLastError(); 
            } 

Waarom roep je WSAGetLastError aan nadat de test op SOCKET_ERROR negatief is uitgevallen?

[ Voor 21% gewijzigd door Olaf van der Spek op 11-10-2003 19:39 ]

Pagina: 1