Daten über einen socket mit recv empfangen führt zu 100% cpu last
-
Neue Infos:
Das abschalten des AV-Programmes (Email-Scan) hat schon viel gebracht
Das zusammen mit den Optimierungen führt dazu, dass die CPU Last über 30% nicht hinauskommt.Dafür ist die Übertragungsrate nun bei nur 1.2MB/Sek.
Wenn ich 8 Threads verwende komme ich auf 4-6MB dafür ist die CPU Last dann wieder bei 100% (30*80=100)?Nachtrag: Das Problem wird durch
m_RecvBuffer += buffer;
verursacht. Ich dachte nicht, dass dies so viel ausmachen würde. Naja.
Wie umgehe ich das am schlauesten? Kann man speicherbereiche erweitern? Quasi immer die 10KB hinten dranhängen?
Stefan
-
ich gehe mal davon aus dass m_RecvBuffer auch ein CString ist. und CString ist für "stückerlweise immer länger machen" nicht gerade optimal geeignet.
als "quick fix" kannst du probieren den CString gleich von anfang an gross genug zu machen, z.B. mit m_RecvBuffer.Preallocate(1024 * 1024).
oder exponentiell wachsen lassen:
if (m_RecvBuffer.GetAllocLength() < (m_RecvBuffer.GetLength() + sizeof(buffer) + 1)) m_RecvBuffer.Preallocate(m_RecvBuffer.GetAllocLength() * 2); m_RecvBuffer += ...;
ich würde das ganze aber etwas anders angehen - wozu du allerdings mehr umschreiben müsstest.
ich würde vielleicht erstmal alles in zeilen zerteilen. in der art:class foo { public: foo() : m_carriage_return_seen(false) { } void push(char const* begin, char const* end) { while (begin != end) { push(*begin); ++begin; } } void push(char ch) { m_buffer.push_back(ch); if (m_carriage_return_seen && ch == '\n') { emit_line(); m_buffer.clear(); } m_carriage_return_seen = (ch == '\r'); } void emit_line() { // m_buffer enthält jetzt genau eine zeile text // hier sollte diese zeile jetzt ans nächste glied in der kette weitergereicht werden } private: std::vector<char> m_buffer; bool m_carriage_return_seen; }
dadurch musst du nicht jedes mal alle bereits empfangenen bytes erneut nach einem zeilenumbruch durchsuchen, was einiges an zeit spart.
in der emit_line() funktion leitest du das dann z.b. weiter an eine andere klasse, die sich ums IMAP protokoll ansich kümmert, und die z.b. auf eine zeile in einem bestimmten format wartet.
dazu musst du auch kein "find" verwenden - die meisten protokolle sind so aufgebaut, dass man die "haben fertig" zeilen sehr einfach erkennen kann. zumindest die die ich kenne.beispiel:
void bar::push_line(char const* begin, char const* end) { m_reply_lines.push_back(std::string(begin, end)); size_t const line_size = end - begin; // erster check, einfach, für schnelle "rejection" der meisten unpassenden zeilen if (line_size >= 5 && begin[0] == 'I' // nur ein beispiel, ich hab keine ahnung vom IMAP protokoll && begin[1] == 'M' && begin[2] == 'A' && begin[3] == 'P' && begin[4] == '_') { // genauer check ob es die gesuchte zeile ist if (...) { process_command_reply(); m_reply_lines.clear(); } } }
ich will damit nur grob ne richtung andeuten, wie man halbwegs schnell und halbwegs sauber (und IMO mit vertretbarem aufwand) zeilenbasierte protokolle parsen kann.
ich hoffe du kannst damit was anfangen.
-
Hallo,
ich habes gefunden. Es ist ein CString::Trim("\r\n ").
Wenn diesen Befehl auf einen 23MB String losläßt dauert das 15Sekunden.
QuadCore 3GHz, 8GB RAM, 64Bit OS. Ramdurchsatz ca. 32GByte/SekundeIch wußte ja das CString nicht so schnell ist, aber das ist doch lächerlich.
Ich lese nun direkt in den Buffer des CString mittels GetBufferSetLength und ReleaseBuffer. Wenn der Buffer zu klein wird kopiere ich ihn in einen doppelt so großen. Das optimiere ich dann später.
Bei RecvIntoBuffer lese ich nun solange Daten kommen mit einen Select Timeout von 250ms.
while (SocketReadable(m_Socket) == TRUE)
{
}Vielen Dank für Eure Hilfe!
Das hätte ich so wohl nicht gefunden!Stefan
PS: ich mag keine Klartextprotkolle!
-
Klartextprotokolle sind das Beste wo gibt
-
Ramdurchsatz ca. 32GByte/Sekunde
Gerücht!
-
hustbaer schrieb:
Klartextprotokolle sind das Beste wo gibt
Sagt Jemand der eine Taschenlampe für ein 500 Euro Smartphone programmiert hat :xmas2:
-
StefanKittel schrieb:
hustbaer schrieb:
Klartextprotokolle sind das Beste wo gibt
Sagt Jemand der eine Taschenlampe für ein 500 Euro Smartphone programmiert hat :xmas2:
Von mir ist nur der Windows Port
BTW: doch kein Gerücht. Hab mich grad schlau gelesen. Wahnsinn. Will auch einen i7
-
hustbaer schrieb:
Klartextprotokolle sind das Beste wo gibt
Du bist altmodisch.
Das heisst: "Klartextprotokoll sind s'bescht, wos je häts gits." (ca. 3:50)@hustbaer
Ich finde es wahnsinnig, wie Konsistent sich dein Programm auf den verschiedenen System verhält. Wie kriegst du das nur hin, dass gleich aussieht? :p
-
drakon schrieb:
@hustbaer
Ich finde es wahnsinnig, wie Konsistent sich dein Programm auf den verschiedenen System verhält. Wie kriegst du das nur hin, dass gleich aussieht? :pIn der Tat. Pixelgenau gleich.
D:\Downloads>fc screen-java-windows.png screen-java-linux.png Vergleichen der Dateien screen-java-windows.png und SCREEN-JAVA-LINUX.PNG FC: Keine Unterschiede gefunden D:\Downloads>fc screen-java-windows.png screen-java-macosx.png Vergleichen der Dateien screen-java-windows.png und SCREEN-JAVA-MACOSX.PNG FC: Keine Unterschiede gefunden
Will auch einen i7.
-
volkard schrieb:
drakon schrieb:
@hustbaer
Ich finde es wahnsinnig, wie Konsistent sich dein Programm auf den verschiedenen System verhält. Wie kriegst du das nur hin, dass gleich aussieht? :pIn der Tat. Pixelgenau gleich.
Phu.. Ich habe es vermutet, aber das es wirklich so gleich ist, hätte ich nie erwartet..