Hallo,
ich beschäftige mich schon eine ganze Weile inzwischen mit NIO. ICh bin dabei eine Netzwerkbibliothek zu schreiben.
Sprich Klassen, die die Kommunikation via NIO vereinfachen sollen. Ich bin nun halbwegs fertig, sprich ich habe eine funktionierende Version.
Mein Problem:
Wenn ich z.B. random Bytes (Also einfach ein 50 mb ByteBuffer z. B.) über mein Netzwerk an einen anderen Rechner schicke (100 mbit Netzwerk), dann erreiche ich leider nur 40 % der Netzbandbreite. Diese Zahl habe ich dem "TaskManager" entnommen. Wenn ich aber nun z.b. eine Datei in einen freigegebenen Ordner kopiere, so ist die Auslastung rund 85-95 % ... Nun stelle ich mir die Frage, wo der Fehler liegen kann in meiner Klassen Sammlung.
Ich könnte jetz natürlich einfach die rund 20 Klassen hier posten, aber ich denke, dass niemand Lust hat, sich in soviele Klassen einzuarbeiten, vorallem, weil ich noch keine Dokumentation habe. Deshalb beschreibe ich den Grundaufbau meines Programmes, damit (falls ich z.B. einen typischen "Anfängerfehler" gemacht habe) ihr mir vlt. helfen könnt.
Ich habe eine Mainschleife, in der select() aufgerufen wird und die jeweiligen Ereignisse ausgewertet werden. Wenn von einem channel gelesen werden kann, so geschieht dies in einem eigenen Thread. Während dessen, wird dieser Channel von OP_READ gestrichen, damit nicht parallel gelesen wird. Nachdem gelesen wurde, wird eine "onRead()" Methode innerhalb des eigenen Lesethreads aufgerufen.
Alle Thread werden in einem Threadpool ausgeführt...
Ich verwende zur Zeit einen FixedPoolThread
Geschrieben wird in der Mainschleife, da ich mir hab sagen lassen, dass das schreiben so schnell geht, dass es keinen Geschwindigkeits (bzw. so wenig, dass es sich nicht lohnt) -vorteil bringt.
So, ich habe zur Zeit folgendes Testszenario:
1x Serverprogramm, dass auf Rechner A läuft...
1x Clientprogramm, dass auf Rechner B läuft...
Nun verschicke ich 8096 byte Blöcke. Ein Block wird erst dann gesendet, wenn die send-Methode wieder zurückkehrt, sprich es wird kein riesen Puffer im Hintergrund aufgebaut oder so, der das Programm durch Overhead verlangsamen könnte...
Gelesen wird ebenfalls in 8096 byte Blöcken... Jedes Mal bei Read in einem eigenen Thread, wird 1. gelesen, 2. eine Variable (long counter) um den Wert erhöht, der empfangen wurde... Damit man irgendwo ein Ende hat...
Nach diesen beiden Dingen, wird der Channel wieder auf OP_READ gesetzt und der Thread wird verlassen. Da natürlich direkt wieder Daten zum empfangen da sind, wird direkt wieder in einem Thread gelesen.
Ich habe die Vermutung, dass hier evt. zuviel Rechenleistung bei drauf geht. Jedoch spricht folgendes dagegen:
Die CPU-Auslastung ist ca. bei 40-50 % Wenn also die Daten bedingt durch Overhead zu langsam sind, müsste doch die CPU 100% haben oder nicht ?
Desweiteren benutze ich an vielen Stellen in der Mainschleife eine HashMap ... und frage oft Werte darin ab... Aber auch falls diese Listen das Programm verlangsamen würde... auch dann müsste doch die CPU hoch schnellen oder ?
Wenn ihr bis hierhin keinen Fehler erkennt, bin ich ratlos und werde nochmal das komplette Konzept überdenken !
Wenn ihr dennoch bestimmte Codepassagen sehen wollt, so sagt mir welche und ich poste sie ...
Ich bedanke mich schonmal im Vorraus, dass ihr euch meinem Problem annehmt...
Gruß Chris
PS: Frohes neues Jahr!! :lol:
ich beschäftige mich schon eine ganze Weile inzwischen mit NIO. ICh bin dabei eine Netzwerkbibliothek zu schreiben.
Sprich Klassen, die die Kommunikation via NIO vereinfachen sollen. Ich bin nun halbwegs fertig, sprich ich habe eine funktionierende Version.
Mein Problem:
Wenn ich z.B. random Bytes (Also einfach ein 50 mb ByteBuffer z. B.) über mein Netzwerk an einen anderen Rechner schicke (100 mbit Netzwerk), dann erreiche ich leider nur 40 % der Netzbandbreite. Diese Zahl habe ich dem "TaskManager" entnommen. Wenn ich aber nun z.b. eine Datei in einen freigegebenen Ordner kopiere, so ist die Auslastung rund 85-95 % ... Nun stelle ich mir die Frage, wo der Fehler liegen kann in meiner Klassen Sammlung.
Ich könnte jetz natürlich einfach die rund 20 Klassen hier posten, aber ich denke, dass niemand Lust hat, sich in soviele Klassen einzuarbeiten, vorallem, weil ich noch keine Dokumentation habe. Deshalb beschreibe ich den Grundaufbau meines Programmes, damit (falls ich z.B. einen typischen "Anfängerfehler" gemacht habe) ihr mir vlt. helfen könnt.
Ich habe eine Mainschleife, in der select() aufgerufen wird und die jeweiligen Ereignisse ausgewertet werden. Wenn von einem channel gelesen werden kann, so geschieht dies in einem eigenen Thread. Während dessen, wird dieser Channel von OP_READ gestrichen, damit nicht parallel gelesen wird. Nachdem gelesen wurde, wird eine "onRead()" Methode innerhalb des eigenen Lesethreads aufgerufen.
Alle Thread werden in einem Threadpool ausgeführt...
Ich verwende zur Zeit einen FixedPoolThread
Geschrieben wird in der Mainschleife, da ich mir hab sagen lassen, dass das schreiben so schnell geht, dass es keinen Geschwindigkeits (bzw. so wenig, dass es sich nicht lohnt) -vorteil bringt.
So, ich habe zur Zeit folgendes Testszenario:
1x Serverprogramm, dass auf Rechner A läuft...
1x Clientprogramm, dass auf Rechner B läuft...
Nun verschicke ich 8096 byte Blöcke. Ein Block wird erst dann gesendet, wenn die send-Methode wieder zurückkehrt, sprich es wird kein riesen Puffer im Hintergrund aufgebaut oder so, der das Programm durch Overhead verlangsamen könnte...
Gelesen wird ebenfalls in 8096 byte Blöcken... Jedes Mal bei Read in einem eigenen Thread, wird 1. gelesen, 2. eine Variable (long counter) um den Wert erhöht, der empfangen wurde... Damit man irgendwo ein Ende hat...
Nach diesen beiden Dingen, wird der Channel wieder auf OP_READ gesetzt und der Thread wird verlassen. Da natürlich direkt wieder Daten zum empfangen da sind, wird direkt wieder in einem Thread gelesen.
Ich habe die Vermutung, dass hier evt. zuviel Rechenleistung bei drauf geht. Jedoch spricht folgendes dagegen:
Die CPU-Auslastung ist ca. bei 40-50 % Wenn also die Daten bedingt durch Overhead zu langsam sind, müsste doch die CPU 100% haben oder nicht ?
Desweiteren benutze ich an vielen Stellen in der Mainschleife eine HashMap ... und frage oft Werte darin ab... Aber auch falls diese Listen das Programm verlangsamen würde... auch dann müsste doch die CPU hoch schnellen oder ?
Wenn ihr bis hierhin keinen Fehler erkennt, bin ich ratlos und werde nochmal das komplette Konzept überdenken !
Wenn ihr dennoch bestimmte Codepassagen sehen wollt, so sagt mir welche und ich poste sie ...
Ich bedanke mich schonmal im Vorraus, dass ihr euch meinem Problem annehmt...
Gruß Chris
PS: Frohes neues Jahr!! :lol: