[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 SacheWä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.