Hallo,
ich habe eine Struktur mit 6 members
typedef struct
{
uint8 sekunden;
uint8 minuten;
uint8 stunden;
uint8 tag;
uint8 monat;
uint16 jahr;
}time_ts;
time_ts time1_s;
time_ts time2_s;
time1_s wird regelmäßig beschrieben.
time2_s möchte ich auf bestimmte befehle beschreiben.
um nicht alles immer neu ausrechnen zu müssen, schreibe ich die
parameter von time1_s auf time2_s (vor allem tag, monat, jahr)(quasi als
default werte).
Was geht hier am schnellsten?
ein memcpy?
memcpy(&time2_s, &time1_s, sizeof(time_ts));
oder jeden wert einzeln zu schreiben?
time2_s.sekunden = time1_s.sekunden;
....
Antwort 1: Dürfte ziemlich egal sein. Wenn nicht, also wenn es dir
auffällt, dann probier das andere.
Antwort 2: Assignment der ganzen struct "time2_s = time1_s", weil
einfacher zu schreiben und zu lesen und wegen Antwort 1.
Antwort 3: Warum selber einen Datentyp machen wenn <time.h> struct tm
enthält?
Hannes J. schrieb:> Antwort 2: Assignment der ganzen struct "time2_s = time1_s", weil> einfacher zu schreiben und zu lesen und wegen Antwort 1.
Das ist die richtige Antwort. Der Compiler entscheidet dann je nach
Struktur nämlich selbst ob memcpy oder Variablenweises Copy schneller
ist. Um genau zu sein, wird der Compiler sogar nur Teile der Struktur
kopieren wenn er sieht, das diese direkt darauf nochmals (in Teilen)
geschrieben wird.
Dirk B. schrieb:> Hannes J. schrieb:>> time2_s = time1_s>> C kann das mindestens seit 1989.> Die alleresten Compiler (noch mit K&R-C) haben das noch nicht> unterstützt.
Wenn die structs auch in Interrupts gebraucht/geändert werden, muss man
die Zugriffe noch entsprechend schützen bzw. atomar machen (und evtl.
volatile deklarieren), sonst ist da ruck-zuck was ungewollt
wegoptimiert.
Gruß
Robert
mh schrieb:> Frank M. schrieb:>>> memcpy() ist im Zweifel schneller.>> Gibts nen Grund, warum das im Zweifel so ist und nicht vom Fall abhängt?
Meine Aussage galt bzgl. der Frage memcpy() vs. Kopieren der einzelnen
Struct-Members, nicht bzgl. der einfachen Zuweisung time2_s = time1_s,
was vermutlich auf dasselbe wie der memcpy() hinausläuft.
Eine Antwort auf Deine Frage findest Du hier:
https://www.embedded.com/optimizing-memcpy-improves-speed/
Zusammengefasst: memcpy() optimiert auf geeigneten Prozessoren, indem
nicht byteweise, sondern in größeren Brocken kopiert wird. Das hängt
u.a. davon ab, wie die Struktur aligned ist. Ebenso trägt das Caching
und die Write-Policy zur Performance-Steigerung von memcpy() bei.
Wenn man das alles nicht genau weiß und abschätzen kann, ist memcpy() im
Zweifel schneller als mehrere Einzelzuweisungen der Stuct-Members. Unter
obigem Link findest Du eindrucksvolle Graphiken dazu.
Frank M. schrieb:> mh schrieb:>> Frank M. schrieb:>>> memcpy() ist im Zweifel schneller.>> Gibts nen Grund, warum das im Zweifel so ist und nicht vom Fall abhängt?> [...]> Eine Antwort auf Deine Frage findest Du hier:> https://www.embedded.com/optimizing-memcpy-improves-speed/> Zusammengefasst: memcpy() optimiert auf geeigneten Prozessoren, indem> nicht byteweise, sondern in größeren Brocken kopiert wird.
Das zeigt noch nicht, dass memcpy immer gleich schnell oder schneller
ist. Das behauptest du aber mit "im Zwiefel". Vor allem (aber nicht
ausschließlich), da wir hier in PC und nicht im µC Teil des Forums sind.
Auf nem modernen x86_64 ist "schnell" ne komplizierte Sache.
mh schrieb:> Das zeigt noch nicht, dass memcpy immer gleich schnell oder schneller> ist. Das behauptest du aber mit "im Zwiefel".
Das hattest Du falsch verstanden. Wenn ich "immer" gemeint hätte, dann
hätte ich auch "immer" geschrieben.
Mit "im Zweifel" meinte ich: Wenn man es nicht genau weiß, wie der
Prozessor/Compiler arbeitet (der TO zweifelt beispielsweise), macht man
mit memcpy() nichts verkehrt. Man programmiert ja auch in C und nicht in
Assembler, weil man portable Programme schreiben will, die vielleicht
später mal auf einen moderneren Prozessor portiert werden.
Ich jedenfalls optimiere nie auf einen bestimmten µC, sondern ich
überlasse das "im Zweifel" der libc und dem Compiler. Mit dieser
Strategie fährt man ganz gut, siehe IRMP, der auf den
verschiedensten µC-Familien gleich gut läuft.
Zu Deiner Bemerkung "Wir sind hier unter PC und nicht µC": Du hättest
Dir den von mir aufgeführten Artikel mal näher anschauen lesen sollen
statt relexartig zu antworten. Gerade ein Prozessor im PC profitiert vom
optimierten memcpy().
Frank M. schrieb:> Das hattest Du falsch verstanden. Wenn ich "immer" gemeint hätte, dann> hätte ich auch "immer" geschrieben.>> Mit "im Zweifel" meinte ich: Wenn man es nicht genau weiß, wie der> Prozessor/Compiler arbeitet (der TO zweifelt beispielsweise), macht man> mit memcpy() nichts verkehrt.> [...]
Schön, dass du das gemeint hast. Du hast aber geschrieben
Frank M. schrieb:> memcpy() ist im Zweifel schneller.
Das ist etwas anderes als "Im Zweifel macht man mit memcpy nichts
verkehrt".
mh schrieb:> Schön, dass du das gemeint hast. Du hast aber geschrieben
Wir haben halt ein verschiedenes Verständnis von der Formulierung "Im
Zweifel".
Zu Deiner Bemerkung "Wir sind hier unter PC und nicht µC": Du hättest
Dir den von mir aufgeführten Artikel mal näher anschauen sollen statt
relexartig zu antworten. Gerade ein Prozessor im PC profitiert vom
optimierten memcpy(), blättere dort mal weiter runter.
Und jetzt ist hier EOD für mich. Deine Haarspalterei erzeugt bei mir
jedenfalls den Eindruck, dass Du hier Zoff wegen einer Formulierung
anfangen willst. Dazu habe ich keinen Bock.
Frank M. schrieb:> mh schrieb:>> Schön, dass du das gemeint hast. Du hast aber geschrieben>> Wir haben halt ein verschiedenes Problem von der Formulierung "Im> Zweifel".
Du behauptest memcpy ist im Zweifel schneller. Ich habe Zweifel daran,
dass memcpy schneller ist. Als logische Volgerung dieser beiden Aussagen
ist memcpy schneller. Hätte ich keine Zweifel, wäre memcpy vielleicht
nicht schneller?
Frank M. schrieb:> Und jetzt ist hier EOD für mich. Deine Haarspalterei erzeugt bei mir> jedenfalls den Eindruck, dass Du hier Zoff anstiften willst. Dazu habe> ich keinen Bock.
Du magst es Haarspalterei nennen. Ich wollte einfach nur wissen, warum
deine Antwort so absolut war.
Der Chef schrieb:> Wenn die structs auch in Interrupts gebraucht/geändert werden, muss man> die Zugriffe noch entsprechend schützen bzw. atomar machen
Das muß man bei allen genannten Methoden so machen.