-
Notifications
You must be signed in to change notification settings - Fork 0
GameFileMapper
Das GameFileMapper Projekt ist ein Hilfsprojekt. Es wurde eingeführt, um die Daten aus der Originaldatei in ein neues, effizienter verarbeitbares Format zu überführen um somit den Leseprozess zu beschleunigen.
Die Sensor-Rohdaten besitzen ein wohlgeformtes Format. Ein typischer Eintrag aus der Aufzeichnung besitzt das Format:
69,10632024809835772,27679,-221,1011,553570,2481132,-9441,2048,2580,-8913,1107,4396
Die Bedeutung der Werte folgt der in der Kommunikationsarchitektur vorgestellten Grundstruktur. Insgesamt wurden während eines Spieles 49.576.081 Einträge aufgezeichnet. Das entspricht einem Datenvolumen von 4.255.018.857 Bytes und einer Eintragsdichte von einem Eintrag pro 86 Bytes.
Um einen Eintrag aus der Originaldatei auszulesen, musste ein unangemessener Verarbeitungsaufwand eingeplant werden. Damit die eigentliche Kernaufgabe des Traffic-Generators, also die Übertragung der Daten in Echtzeit, nicht durch einen zu langsamen Leseprozess gestört wird, soll diese Komponente durch eine höhere Eintragsdichte den Leseprozess beschleunigen.
Die wesentlich interessantere Intention stellt jedoch die Messung der Prozessgrößen dar. Mithilfe der Originaldatei konnte bereits eine echtzeitfähige Kommunikation umgesetzt werden, allerdings wirkt sich die wesentlich ineffizientere Datenstruktur negativ auf den Übertragungsprozess unter Volllast aus. Die Ursache für dieses Verhalten korreliert direkt mit dem hohen Datenvolumen, da das Auslesen der Originaldatei mit 4 GByte bereits wesentlich den Prozessablauf stört. Es soll daher eine Datenstruktur entworfen werden, die durch weniger Redundanz und sinnvolle Aufteilungen den Leseprozess beschleunigt und somit eine sinnvolle, weitestgehend störungsfreie Messung der Übertragungsgeschwindigkeit ermöglicht.
Das Format der Sensor-Rohdaten bietet verschiedene Möglichkeiten der Optimierung an. Das erste Problem stellt das menschenlesbare Format dar. Will man beispielsweise den ersten Wert eines Eintrages auslesen, können unterschiedliche Verfahren angewendet werden.
Der primitive Ansatz könnte über ein einfaches Splitting der Werte realisiert werden. Da die Werte eines Eintrages über einen vorgeschriebenen Delimiter (,) getrennt werden, kann natürlich jeder Eintrag mit einem regulären Ausdruck in seine Bestandteile zerlegt werden. Dieser Ansatz würde aufgrund der bereits durch Java umgesetzten Vorverarbeitung und der zusätzlich langsamen Verarbeitung des regulären Ausdrucks zu Performance-Einbußen führen (auch wenn sie vernachlässigbar sind).
Als alternativen Ansatz könnte man versuchen die Daten sequentiell auszulesen und somit die Verarbeitung zu beschleunigen. Der interessante Faktor bei diesem Ansatz ist natürlich die einmalige Datenverarbeitung. Wenn ein Wert gelesen werden soll, muss solange ein Lesepuffer gefüllt werden bis der Delimiter auftritt. Schließlich kann der Puffer in einen realen Wert umgewandelt und der Puffer gelöscht werden. Dies führt bereits zu einer wesentlich höheren Performance, da die gesamte Vorverarbeitung durch Java wegfällt und sogar die Auswertung eines regulären Ausdrucks direkt durchgeführt werden kann. Eine ähnliche Umsetzung würde sich entsprechend für die neue Datenstruktur anbieten.
Besonders beim sequentiellen Auslesen der Daten erkennt man jedoch, dass einige Potentiale noch ungenutzt bleiben. Obwohl bei beiden Ansätzen bereits ein "Vorpuffern" von größeren Datenblöcken stattfinden sollte, können in beiden Fällen die Größe/Länge eines Wertes variieren. Das führt dazu, dass man stets einen Test auf den sowieso irrelevanten Delimiter durchführen muss. Für eine optimale Verarbeitung wäre es ideal, wenn man die Länge eines Wertes kennt und sofort den Wert auslesen kann. Die angestrebte und auch schließlich auch umgesetzte Lösung wandelt daher die dezimalen Werte in ein Binärformat mit einer festen Breite pro Wert um. Die somit gespeicherten Werte besitzen dabei die Länge der Typen, wie sie in der Datengrundlage definiert sind (Integer: 4 Byte, Long: 8 Byte). Da es sich zudem nur um ein einheitliches Datenformat handelt, können die Daten auch ohne Delimiter abgelegt werden.
Das neue Datenformat folgt nun dem Schema:
4 Byte (int), 8 Byte (int), 11 * 4 Byte (int)
//TODO: Vergleiche (Größe: 2.776.260.480 Bytes, Eintragsdichte: 1 Eintrag pro 56 Byte) => Vorteile