Kopieren von fortlaufenden Daten in C ++

8

Ich habe zwei Arrays und möchte ein Array mit einem Schritt in das andere kopieren. Zum Beispiel habe ich

%Vor%

und ich möchte alle drei Elemente von B nach A kopieren, um

zu erhalten %Vor%

Aus dem Post " Gibt es eine Standardversion von memcpy, die in Schritten angezeigt wird? ? ", so scheint es in C keine solche Möglichkeit zu geben.

Ich habe jedoch festgestellt, dass memcpy in manchen Fällen schneller ist als% for auf Schleifen basierende Kopie.

Meine Frage ist; Gibt es eine Möglichkeit, die Speicherkopie in C ++ effizient auszuführen, indem mindestens die standardmäßige for Schleife ausgeführt wird?

Vielen Dank.

BEARBEITEN - KLARIFIZIERUNG DES PROBLEMS

Um das Problem zu verdeutlichen, lassen Sie uns die beiden verfügbaren Arrays mit a und b bezeichnen. Ich habe eine Funktion, die die einzigartige folgende for Schleife

ausführt %Vor%

Dabei sind beide [] überladene Operatoren (ich benutze eine Expression-Templates-Technik), so dass sie tatsächlich gemein sein können, zum Beispiel

%Vor%     
JackOLantern 13.06.2013, 15:13
quelle

2 Antworten

6
%Vor%

Bearbeiten 2: Es gibt keine Funktion zum schrittweisen Kopieren in den C ++ - Bibliotheken.

Da schrittweises Kopieren beim Kopieren eines Speichers nicht so beliebt ist, haben Chiphersteller oder Sprachdesigns spezialisierte Unterstützung für schrittweises Kopieren.

Unter der Annahme einer standardmäßigen for -Schleife können Sie mit Loop Unrolling möglicherweise etwas Leistung erzielen. Einige Compiler verfügen über Optionen zum Loeschen von Schleifen. Es ist keine "Standard" -Option.

Gegeben eine Standard for Schleife:

%Vor%

Beim Schleifenausrollen wird der Inhalt der "standard" for Schleife wiederholt:

%Vor%

In der entrollten Version wurde die Anzahl der Schleifen halbiert.

Die Leistungsverbesserung kann im Vergleich zu anderen Optionen vernachlässigbar sein. Die folgenden Probleme wirken sich auf die Leistung aus und haben möglicherweise unterschiedliche Geschwindigkeitsverbesserungen:

  • Verarbeitungsdatencache vermisst
  • Neuladen der Befehlspipeline (abhängig vom Prozessor)
  • Betriebssystem, das den Speicher mit dem Datenträger austauscht
  • Andere Aufgaben, die gleichzeitig ausgeführt werden
  • Parallele Verarbeitung (abhängig von Prozessor / Plattform)

Ein Beispiel für die parallele Verarbeitung besteht darin, dass ein Prozessor die B-Elemente in das neue Array kopiert und ein anderer Prozessor die A-Elemente in das neue Array kopiert.

    
Thomas Matthews 13.06.2013, 20:45
quelle
6

Könnte eine zu genaue Antwort sein, aber auf einer ARM-Plattform, die NEON unterstützt, kann die NEON-Vektorisierung verwendet werden, um eine beschleunigte Kopie noch schneller zu machen. Dies könnte in einer Umgebung, in der die Ressourcen relativ begrenzt sind, lebensrettend sein, und deshalb wird ARM wahrscheinlich in dieser Umgebung eingesetzt. Ein prominentes Beispiel ist Android, wo die meisten Geräte immer noch die ARM v7a-Architektur verwenden, die NEON unterstützt.

Die folgenden Beispiele demonstrieren dies, es ist eine Schleife, um die semi-planare UV-Ebene eines YUV420sp-Bildes in die planare UV-Ebene eines YUV420p-Bildes zu kopieren. Die Größen der Quell- und Zielpuffer sind beide 640*480/2 bytes. Alle Beispiele sind mit dem g ++ 4.8 in Android NDK r9d kompiliert. Sie werden auf einem Samsung Exynos Octa 5420 Prozessor ausgeführt:

Stufe 1: Regulär

%Vor%

Nur mit -O3 kompiliert, dauert durchschnittlich etwa 1,5 ms.

Level 2: Mit bewegten Zeigern abgerollt und gequetscht

%Vor%

Nur mit -O3 kompiliert, dauert durchschnittlich etwa 1,15 ms. Dies ist wahrscheinlich so schnell, wie es bei einer normalen Architektur der Fall ist, wie bei der anderen Antwort.

Level 3: Reguläre + GCC automatische NEON-Vektorisierung

%Vor%

Kompiliert mit -O3 -mfpu=neon -ftree-vectorize -ftree-vectorizer-verbose=1 -mfloat-abi=softfp dauert im Durchschnitt etwa 0,6 ms. Als Referenz benötigt ein memcpy von 640*480 Bytes, oder die doppelte Menge von dem, was hier getestet wird, im Durchschnitt etwa 0,6 ms.

Als Randnotiz dauert der zweite Code (entrollt und pointiert), der mit den obigen NEON-Parametern kompiliert wurde, ungefähr die gleiche Zeit, 0,6 ms.

    
Ayberk Özgür 07.10.2014 07:56
quelle

Tags und Links