Bytewechsel während der Kopie

8

Ich muss die Byte-Reihenfolge eines Arrays beim Kopieren in ein anderes Array effizient austauschen.

Das Quell-Array ist von einem bestimmten Typ; char, short oder int so das Byte Swapping erforderlich ist eindeutig und wird entsprechend diesem Typ sein.

Ich plane dies sehr einfach mit einer byteweisen Multi-Pass-Kopie (2 kurz, 4 für int, ...). Gibt es jedoch bereits vorhandene "memcpy_swap_16 / 32/64" -Funktionen oder Bibliotheken? Vielleicht in der Bildverarbeitung für BGR / RGB-Bildverarbeitung.

BEARBEITEN

Ich weiß, wie man die Bytes einzelner Werte vertauscht, das ist nicht das Problem. Ich möchte diesen Prozess während einer Kopie machen, die ich sowieso ausführen werde .

Wenn ich zum Beispiel ein Array oder kleine 4-Byte-Ganzzahlen habe, kann ich sie austauschen, indem ich 4 byteweise Kopien mit Anfangsoffsets von 0, 1, 2 und 3 mit einer Schrittweite von 4 durchführe bessere Möglichkeit, vielleicht sogar jede 4-Byte-Ganzzahl einzeln zu lesen und die Byte-Swap-Eigenschaftswerte _byteswap_usort, _byteswap_ulong und _byteswap_uint64 zu verwenden, wäre schneller. Aber ich vermute, dass es existierende Funktionen geben muss, die diese Art der Verarbeitung durchführen.

EDIT 2

Gerade gefunden, was eine nützliche Grundlage für SSE sein kann, obwohl es wahr ist, dass Speicherbandbreite es wahrscheinlich eine Zeitverschwendung macht.

Schnelle vektorisierte Konvertierung von RGB zu BGRA

    
hplbsh 08.09.2011, 02:31
quelle

3 Antworten

1

Ja, es gibt Funktionen wie die in der Frage verlinkte, aber es lohnt sich nicht, da die Größe der Daten (in diesem Fall) bedeutet, dass der Einrichtungsaufwand zu hoch ist. Also, stattdessen ist es besser, nur 2, 4 und 8 Bytes gleichzeitig auszulesen und den Austausch mit intrinsics durchzuführen und zurückzuschreiben.

    
hplbsh 13.09.2011, 17:17
quelle
6

Unix-Systeme haben eine swab -Funktion, die das was Sie für 16-Bit-Arrays tun wollen. Es ist wahrscheinlich optimiert, aber ich bin mir nicht sicher. Beachten Sie, dass der moderne gcc sehr effizienten Code generiert, wenn Sie nur den naiven Byte-Swap-Code schreiben:

%Vor%

d. Es wird die Anweisung bswap auf i486 + verwenden. Vermutlich wird dies auch zu einer effizienten Schleife führen ...

Bearbeiten: Für Ihre Kopieraufgabe würde ich Folgendes in Ihrer Schleife tun:

  1. Liest einen 32-Bit-Wert aus const uint32_t *src .
  2. Verwenden Sie den obigen Code, um es zu tauschen.
  3. Schreiben Sie einen 32-Bit-Wert in uint32_t *dest .

Streng genommen ist das vielleicht nicht portabel (Aliasing-Verletzungen), aber solange die Kopierfunktion in einer eigenen Übersetzungseinheit ist und nicht inline ist, gibt es wenig zu befürchten. Vergiss, was ich geschrieben habe über Aliasing; Wenn Sie die Daten als 32-Bit-Werte austauschen, waren es fast sicher 32-Bit-Werte, nicht irgendein anderer Pointer-Typ, der ausgegeben wurde. Es gibt also kein Problem.

    
R.. 08.09.2011 02:49
quelle
3

Unter Linux sollten Sie den Header bits/byteswap.h überprüfen. Es gibt eine Familie von Makros in der Form bswap _ ##, und einige von ihnen verwenden gegebenenfalls Montageanweisungen.

    
Foo Bah 08.09.2011 03:07
quelle

Tags und Links