Herakles
Profifragensteller
Moin!
Ich habe soeben etwas herausgefunden, was mich doch sehr verwundert hat. Ich stelle hier also jetzt ausnahmsweise mal keine Frage, sondern stelle einfach mal kurz ein Ergebnis vor.
Man denke sich ein Producer-Consumer Umfeld. Es kommen immer gleichgroße Pakete herein, die - einmal die volle Größe erreicht - anschließend zu verarbeiten sind. Die Pakete sind 512 Bytes groß.
Es bietet sich für dieses spezielle Problem kein Ringpuffer an, weil für den Fall, dass keine neuen Pakete eintrudeln, die alten Daten immer und immer wieder verwendet werden sollen. Also ist es einfacher, sich ein Kopierdatenfeld aufzumachen, in dem immer die zu verwendenden Daten stehen, als aufzupassen, ob neue Daten im Ringpuffer sind - obwohl, so blöd ist die Idee gar nicht fällt mir gerade auf. Naja, darum soll es hier nicht gehen
Ich habe mich gefragt, ob es wohl schneller geht, ein memcpy zu machen, in dem ich die 512 Byte von einem Speicher in einen anderen kopiere, oder ob ich einen Pointer verschiebe(Zugriff auf die alten Daten) und ein malloc mache(für die neu eintreffenden Daten). Das Interessante ist, dass das memcpy schneller geht.
Getestet habe ich das auf einem Atmel AVR32UC3A0512. Ich messe mit einem Oszilloskop immer die Dauer zwischen "port_low()" und "port_high()"(damit schalte ich einfach nur einen Pin, um eine Zeit messen zu können).
Hier mal ein wenig Pseudo-Code:
Mit memcpy:
Mit malloc und pointerverschieben:
Das Ergebnis: Mit memcpy dauert der Vorgang 10us, mit malloc und pointerverschieben 16us.
Entweder das liegt daran, dass entweder malloc oder free viel Zeit benötigen, oder die höhere Anzahl an Befehlen bewirkt in Assembler längeren Code und der Prozessor muss einfach mehr machen.
Wundern tut es mich dennoch, denn es geht hier immerhin um das Kopieren von 512 Bytes. Erwartet hätte ich es genau andersherum.
Wie gesagt, keine Fragestellung hier, sondern einfach nur ein Aufschreiben für die Nachwelt(und sicher auch für mich selbst zum Nachschlagen in 10 Jahren )
Viele Grüße
Herakles
Ich habe soeben etwas herausgefunden, was mich doch sehr verwundert hat. Ich stelle hier also jetzt ausnahmsweise mal keine Frage, sondern stelle einfach mal kurz ein Ergebnis vor.
Man denke sich ein Producer-Consumer Umfeld. Es kommen immer gleichgroße Pakete herein, die - einmal die volle Größe erreicht - anschließend zu verarbeiten sind. Die Pakete sind 512 Bytes groß.
Es bietet sich für dieses spezielle Problem kein Ringpuffer an, weil für den Fall, dass keine neuen Pakete eintrudeln, die alten Daten immer und immer wieder verwendet werden sollen. Also ist es einfacher, sich ein Kopierdatenfeld aufzumachen, in dem immer die zu verwendenden Daten stehen, als aufzupassen, ob neue Daten im Ringpuffer sind - obwohl, so blöd ist die Idee gar nicht fällt mir gerade auf. Naja, darum soll es hier nicht gehen
Ich habe mich gefragt, ob es wohl schneller geht, ein memcpy zu machen, in dem ich die 512 Byte von einem Speicher in einen anderen kopiere, oder ob ich einen Pointer verschiebe(Zugriff auf die alten Daten) und ein malloc mache(für die neu eintreffenden Daten). Das Interessante ist, dass das memcpy schneller geht.
Getestet habe ich das auf einem Atmel AVR32UC3A0512. Ich messe mit einem Oszilloskop immer die Dauer zwischen "port_low()" und "port_high()"(damit schalte ich einfach nur einen Pin, um eine Zeit messen zu können).
Hier mal ein wenig Pseudo-Code:
Mit memcpy:
Code:
void *P, *Q;
Q=malloc(512);
P=malloc(512);
port_low();
memcpy(P,Q,512);
port_high();
Mit malloc und pointerverschieben:
Code:
void *P, *Q, *T;
Q=malloc(512);
port_low();
P=malloc(512);
T=Q;
Q=P;
free(T);
port_high();
Das Ergebnis: Mit memcpy dauert der Vorgang 10us, mit malloc und pointerverschieben 16us.
Entweder das liegt daran, dass entweder malloc oder free viel Zeit benötigen, oder die höhere Anzahl an Befehlen bewirkt in Assembler längeren Code und der Prozessor muss einfach mehr machen.
Wundern tut es mich dennoch, denn es geht hier immerhin um das Kopieren von 512 Bytes. Erwartet hätte ich es genau andersherum.
Wie gesagt, keine Fragestellung hier, sondern einfach nur ein Aufschreiben für die Nachwelt(und sicher auch für mich selbst zum Nachschlagen in 10 Jahren )
Viele Grüße
Herakles