[gelöst] CPU Auslastung Linux vs. Windows ( nach Portierung: win -> linux )



  • Hallo,
    eine Frage beschäftigt mich sehr. Ein Programm wurde von Windows nach Linux
    portiert. Beide Versionen machen auch was sie sollen. Es wird ein Protokoll
    auf UDP-Socket basierend von der Anwendung verarbeitet. Der Server sendet recht
    viele Packete und das sehr schnell.

    Unter Windows liegt die CPU Auslastung lt. Anzeige Taskmanager bei unter 5%.
    Unter Debian Lenny ( in einer VM Ware auf WinXP ) zeigt 'top' eine Auslastung
    für den Prozess von 98%-99% an.

    Meine Frage nun, da es der einzige Prozess ist der tatsächlich was macht, gibt
    Linux diesem Prozess die komplette Prozessorleistung oder stimmt da was nicht
    an der Anwendung ?

    Die Last verteilt sich auf ~30%user und 70%system, lt. top

    Grundsätzlich handelt es sich um eine Endlosschleife aus select, recv und der
    Datenverarbeitung - bis der Thread beendet wird.

    Wird in der Schleife 20ms gewartet sinkt die last auf 8-30%, das ist aber nicht
    Sinn der Sache 🙄

    Während der Verarbeitung wird jedes Mal wenig(!) Speicher allokiert und freigegeben.

    Beste Grüße, RB



  • könnte an der vm liegen, vielleicht muss sie irgendwas simulieren was außerhalb der vm auf hardware laufen kann. ich würde mal gucken wie die performance nativ auf linux ist.



  • Könnte es sein, dass du bei select aus Versehen angegeben hast, dass es nicht blockieren soll? Windows ignoriert ja bekanntermaßen den ein oder anderen Standard.

    Ansonsten kann man ohne den Quelltext nicht viel sagen, ohne zu raten. Normalerweise sollte das, was du beschrieben hast, nicht der Fall sein.



  • Guten Morgen, Danke Euch beiden.

    ich kann es nicht testen weil der "Gegenspieler" offline ist, aber
    Linux ( jetzt )
    select(1 /(int)pnetCtx->socket+1/, &fds, NULL, NULL, timeout);

    Windows + Linux ( vorher )
    select((int)pnetCtx->socket+1, &fds, NULL, NULL, timeout);

    Da war doch was mit den Descriptoren 😕

    ich bin drauf gekommen, weil ein 'sleep' in der Schleife ja etwas hilft.
    select scheint wirklich nicht zu blokieren, mit setsockopt wurde aber nicht
    weiter rumgespielt, weshalb ich mal behaupten möchte die sind blockierend.

    Was anderes wurde unter Windows auch nicht gewünscht oder festgestellt.

    Wenn der erste Parameter bei select nun 'falsch' ist und select ständig
    Fehler feststellt auf Sockets die es garnicht gibt ~ resultiert das doch
    in einer 'harten' Endlosschleife.

    ich werds später testen und ggf. verbesssern können.

    Grüße RB

    [EDIT]
    <snip>
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    while( client->AGENT_INFO.IsLogin && (rc=netSelect(client->udp_base.net, &timeout)) >= 0 )

    int netSelect(netContextPtr pnetCtx, struct timeval* timeout)
    {
    fd_set fds;
    FD_ZERO(&fds);
    FD_SET(pnetCtx->socket, &fds);
    return select((int)pnetCtx->socket+1, &fds, NULL, NULL, timeout);
    }
    </snip>

    ich habe feststellen können, select liefert ständig TimeOuts obwohl die Pakete
    viel schneller ankommen sollten.

    die TimeOuts kommen aber nur unter linux !



  • Linux:
    select manipuliert die Werte in der timeout Struktur.
    Windos:
    behält die Werte in der übergebenen Struktur bei.

    Lösung:
    setzte die Werte für TimeOut vor jedem Aufruf von select() neu.

    vorher:
    timeout.tv_sec = 1;
    timeout.tv_usec = 500;
    while( select() >= 0 ) {...}

    nachher:
    timeout.tv_sec = 1;
    timeout.tv_usec = 500;
    while( select() >= 0 ) {
    ...
    timeout.tv_sec = 1;
    timeout.tv_usec = 500;
    }

    oder eine Wrapper-Funktion my_select() verwenden.



  • btw. solltest du unter Linux lieber epoll benutzen bzw. libevent, wenn du es portabel haben willst.


Anmelden zum Antworten