mehrere Elemente eines Arrays gleichzeitig kopieren
-
Hallo!
Sowas hier geht doch sicherlich auch in einer Zeile, nicht wahr?
Ich meine ich hätte das auch schon mal gesehen, aber leider
komm ich nicht mehr drauf und finde auch nix.point1[0] = vertices[j*3+0]; point1[1] = vertices[j*3+1]; point1[2] = vertices[j*3+2];Wäre super wenn mir jemand fix helfen könnt!

-
std::copy(&vertices[j*3], &vertices[j*3+3], &point1[0]);Und falls es sich um POD-Arrays handelt kann man auch memcpy verwenden, was dir sicherlich gleich jemand erklären wird.
-
SeppJ schrieb:
Und falls es sich um POD-Arrays handelt kann man auch memcpy verwenden,
Muss man aber nicht. Das std::copy aus libstdc++ ist so schlau (erkennt hintereinander im Speicher liegende PODs), dass ein manuelles memcpy keinen Vorteil bringt.
#include <algorithm>
Wenn es Arrays oder Zeiger sind:
std::copy(vertices+(j*3), vertices+(j*3+3), point1+0); von bis wohinWenn es
std::vectoren sind:std::copy(vertices.begin()+(j*3), vertices.begin()+(j*3+3), point1.begin()+0); von bis wohin
-
Hoppala, ich habe oben in meinem Beispiel Quelle und Ziel vertauscht. Habe es jetzt angepasst, dass es zum Beispiel in der Fragestellung passt.
-
Sebastian Pizer schrieb:
Muss man aber nicht. Das std::copy aus libstdc++ ist so schlau (erkennt hintereinander im Speicher liegende PODs), dass ein manuelles memcpy keinen Vorteil bringt.
Die std::copy Implementierung die ich "kenne" (MSVC) ist ziemlich doof, und verlässt sich darauf, dass der Compiler erkennt dass hier PODs kopiert werden.
Der MSVC (getestet mit Version 9) erkennt das auch halbwegs (siehe unten) gut.
Beispiel:template <class InIt, class OutIt> void my_copy(InIt b, InIt e, OutIt d) { for (; b != e; ++b, ++d) *d = *b; } struct some_pod { int a; int b; }Getestet mit einem Array aus jeweils 10000 Elementen:
char/unsigned char/signed char:
memcpy
short/wchar_t:rep movs (5000x dword)
int:rep movs (10000x dword)
some_pod:rep movs (20000x dword)Mit 10001 short/wchar_t:
rep movs (5000x dword) + einzelnes movs (word)Warum er nicht überall
memcpyverwendet verstehe ich nicht so ganz...Es hat auch mit der Grösse nicht viel zu tun, MSVC nimmt auch bei 200 chars
memcpyund bei 200 shortsrep movs.
-
früher war das so, daß die memcpy.asm was furchbar schlaues gemacht hat. mit supi tricks wurden die daten in viererpäckchen halt mit rep mov kopiert, aber halt gut aligned, also vorher und nachher noch null bis drei einzelbytes kopiert. war halt schneller als rep movb byteweise.
aber wenn deine short-daten schon 4-byte-aligned sind, braucht man den zaubercode ja gar nicht und kann gleich losrocken. vielleicht legt er char-arrays nur 1-byte-alignes ab und stellt sich damit dann ein bein. nur mal so in den wind vermutet.
-
Jo ... keine Ahnung

Wobei man rep movs schon noch toppen kann, auch wenn man bei perfektem Alignment etc. vergleicht. Mit den MMX/SSE Registern geht das soweit ich weiss noch einiges mehr. Dafür sind die Setup-Kosten dieser Varianten deutlich höher, zahlt sich also erst bei grösseren Blöcken aus.
-
Bei größeren Datenmengen müsste der Speicherzugriff der Flaschenhals sein (Latenz und Bandbreite). Der Speicher ist im Verhältnis zu heutigen CPUs sehr langsam. Das mit der Latenz ist bei so einem linearen Zugriff weniger ein Problem, weil moderne CPUs dieses Zugriffsmuster erkennen und Daten aus dem Speicher im Voraus anfordern un den Cache damit füllen.
(Es lohnt sich also, Daten im Speicher auf eine Art zu organisieren, dass größtenteils "linear" drauf zugegriffen wird, dass also keine großen/häufigen Sprünge der Adressen gemacht werden.)
-
Sebastian Pizer schrieb:
Bei größeren Datenmengen müsste der Speicherzugriff der Flaschenhals sein (Latenz und Bandbreite). Der Speicher ist im Verhältnis zu heutigen CPUs sehr langsam.
Naja, ne.
Ein i7 System kann bei linearem Zugriff so an die 20 GB pro Sekunde aus/in dem Hauptspeicher schaufeln. Das sind dann ca. 6 Byte pro Zyklus.
Mit ner einfachen Kopierschleife die Bytes schaufelt kommt man nichtmal in die Nähe von 20 GB/sec.
Es zahlt sich also schon immer noch aus hier etwas "schlauer" zu kopieren.
-
Mit den MMX/SSE Registern geht das soweit ich weiss noch einiges mehr.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-257842-and-highlight-is-.html
-
knivil schrieb:
Mit den MMX/SSE Registern geht das soweit ich weiss noch einiges mehr.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-257842-and-highlight-is-.html
Und was sagt uns dieser Thread? Sind IMO nicht wirklich brauchbare Informationen drin.
Ich *weiss* dass es deutlich schnellere Implementierungen als "rep movs" gibt.