Forum: PC-Programmierung struct kopieren


von Lars (Gast)


Lesenswert?

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;
....

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

memcpy() ist im Zweifel schneller.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

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?

: Bearbeitet durch User
von Andreas M. (amesser)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

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.

von Der Chef (Gast)


Lesenswert?

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

von mh (Gast)


Lesenswert?

Frank M. schrieb:
> memcpy() ist im Zweifel schneller.

Gibts nen Grund, warum das im Zweifel so ist und nicht vom Fall abhängt?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von mh (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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().

: Bearbeitet durch Moderator
von mh (Gast)


Lesenswert?

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".

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von mh (Gast)


Lesenswert?

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.

von Dirk B. (dirkb2)


Lesenswert?

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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.