Frage So kopieren Sie Speicher aus der Quelle, die nicht auf Byte-Ausrichtung (verschoben) ist


Ich kann mir ein paar scheußliche ineffiziente Wege vorstellen, um diese Aufgabe zu erfüllen, aber ich frage mich, was der beste Weg ist.

Zum Beispiel möchte ich 10 Byte beginnend mit dem 3. Bit in einem Byte kopieren und wie gewohnt auf einen Zeiger kopieren.

Gibt es einen besseren Weg als ein Byte nach dem anderen zu kopieren?

Vielen Dank


5
2017-09-17 20:21


Ursprung


Antworten:


Der allgemeine Ansatz besteht darin, den Quellpuffer so effizient wie möglich zu lesen und ihn auf dem Weg zum Schreiben des Zielpuffers nach Bedarf zu verschieben.

Sie müssen keine Byteoperationen ausführen, Sie können immer die Quelllesevorgänge abrufen long für den Großteil der Operation ausgerichtet, indem am Anfang bis zu drei Bytes ausgeführt werden und das Ende gleichermaßen gehandhabt wird, da Sie nicht versuchen sollten, über die angegebene Quellpufferlänge hinaus zu lesen.

Von den gelesenen Werten verschieben Sie sich wie erforderlich, um die gewünschte Bitausrichtung zu erhalten und fertiggestellte Bytes zum Schreiben an das Ziel zusammenzusetzen. Sie können auch die gleiche Optimierung von Schreibvorgängen auf die am weitesten ausgerichtete Wortgröße durchführen.

Wenn Sie in der Quelle nach einem Komprimierungstool oder einer Bibliothek suchen, die umfangreiche Tokens mit variabler Breite verwendet (zlib, MPEG, TIFF und JPEG alle in den Sinn kommen), werden Sie wahrscheinlich Beispielcode finden, der einen Eingabe- oder Ausgabepuffer behandelt ein Strom von Bits, die einige Implementierungsideen zum Nachdenken haben.


5
2017-09-17 20:43



Auf x86 ist die kleinste Einheit, auf die Sie zugreifen können, ein Byte. Sie können jedoch auf 4 Byte gleichzeitig zugreifen und mit 4 Byte gleichzeitig statt mit einem Byte arbeiten. Für höhere Geschwindigkeiten können Sie pslldq (SSE2). Stellen Sie sicher, dass Kopien für maximale Leistung ausgerichtet sind.


3
2017-09-17 20:39



Dies ist die Lösung, die ich programmiert habe und die ich benutzt habe.

void RightShiftMemCopy(uchar * pSource, uchar * pDest ,ushort len,uchar shiftOffset)
{
    ushort i=0;

    pDest+=(len-1);
    pSource+=(len-1);

    for(i=len-1;i != 0 ;--i)
    {
        *pDest = (*(pSource - 1) << 8 | *pSource) >> shiftOffset;

        --pDest;
        --pSource;
    }

    *pDest = *pSource >> shiftOffset;

}

0
2017-09-17 20:32