2010-09-17 6 views
5

Ich kann einige unangenehme ineffiziente Wege vorstellen, um diese Aufgabe zu erfüllen, aber ich frage mich, was der beste Weg ist.So kopieren Sie Speicher aus der Quelle, die nicht auf Byte-Ausrichtung ist (verschoben)

Zum Beispiel möchte ich 10 Bytes ab dem 3. Bit in einem Byte kopieren und wie üblich auf einen Zeiger kopieren.

Gibt es einen besseren Weg, als ein verschobenes Byte zu einem Zeitpunkt zu kopieren?

Dank

+0

Und Sie möchten dies warum tun? –

+0

@Adam: es passiert! – SamB

+0

Ya was @SamB sagte. Ich arbeite mit einem Low-Memory-System und habe einige dicht gepackte Daten. Auch wenn es keinen Sinn ergibt, hatte ich immer noch Lust, die Frage zu stellen. – Ryu

Antwort

5

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 Byte-Operationen ausführen, Sie können immer die Quelle lesen long für den Großteil der Operation ausgerichtet, indem Sie bis zu drei Bytes am Anfang und in ähnlicher Weise behandeln das Ende, da Sie nicht versuchen sollten über die angegebene Quellpufferlänge hinauslesen.

Von den gelesenen Werten verschieben Sie wie erforderlich, um die gewünschte Bitausrichtung zu erhalten und fertige 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), werden Sie wahrscheinlich Beispielcode finden, der eine Eingabe behandelt oder Ausgabepuffer als ein Strom von Bits, der einige Implementierungsideen zum Nachdenken haben wird.

0

Dies ist die Lösung, die ich codiert habe und begann zu verwenden.

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

Rufen Sie 'memcpy()' nicht auf, um ein Byte zu kopieren. Sagen Sie einfach "destData [i] = val". Ihre Verwendung von 'pSource' ist hier eine schlechte Namenswahl. Und seine Verwendung in dem "memcpy" -Aufruf nimmt eine bestimmte Endianz an. – RBerteig

3

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) verwenden. Stellen Sie sicher, dass Kopien für maximale Leistung ausgerichtet sind.

+1

Hat nichts damit zu tun, was der Fragesteller wollte. Er möchte Daten kopieren, die Subbyte-Alignment haben, du sagst ihm nur, wie man ein schlechteres Memcpy implementiert als das, das er bereits hat. – SamB

+2

@SamB: Nicht wirklich. Bitshifting ganze Wörter zu einer Zeit wird viel schneller sein, als es ein Byte zu einer Zeit. –

+0

ja - @R ist richtig. Viel schneller. Sie können die Zyklen pro Anweisung betrachten. Lassen Sie uns nicht voreilige Schlüsse ziehen. – EdH