2010-09-17 6 views
5

Je peux penser à des moyens inefficaces et désagréables pour accomplir cette tâche, mais je me demande quel est le meilleur moyen.Comment copier la mémoire de la source qui n'est pas sur l'alignement des octets (décalé)

Par exemple, je veux copier 10 octets commençant au 3e octet dans un octet et copier dans un pointeur comme d'habitude.

Existe-t-il un meilleur moyen que de copier un octet décalé à la fois?

Merci

+0

Et vous voulez faire cela pourquoi? –

+0

@Adam: ça arrive! – SamB

+0

Ya ce que @SamB a dit. Je travaille avec un système de mémoire faible et j'ai des données très compactes. Même si cela n'a pas de sens, j'ai toujours envie de poser la question. – Ryu

Répondre

5

L'approche générale consiste à lire le tampon source le plus efficacement possible et à le décaler au besoin pour écrire le tampon de destination.

Vous ne devez pas effectuer d'opérations d'octets, vous pouvez toujours obtenir la lecture de la source long alignée pour la majeure partie de l'opération en faisant jusqu'à trois octets au début, et en gérant la fin de la même manière car vous ne devriez pas essayer lire au-delà de la longueur du tampon source indiquée. A partir des valeurs lues, vous changez de valeur si nécessaire pour obtenir l'alignement des bits souhaité et assemblez les octets finis pour l'écriture vers la destination. Vous pouvez également faire la même optimisation des écritures à la plus grande taille de mots alignés possible. Si vous explorez la source d'un outil de compression ou d'une bibliothèque qui utilise intensivement des jetons de largeur variable (zlib, MPEG, TIFF et JPEG), vous trouverez probablement un exemple de code traitant une entrée ou tampon de sortie en tant que flux de bits qui auront des idées d'implémentation à prendre en compte.

0

Ceci est la solution que j'ai codé, et commencé à utiliser.

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

N'appelez pas 'memcpy()' pour copier un octet. Dites simplement 'destData [i] = val'. Votre utilisation de 'pSource' ici est un mauvais choix de nom. Et son utilisation dans l'appel 'memcpy' suppose une endianness particulière. – RBerteig

3

Sur x86, la plus petite unité à laquelle vous pouvez accéder est un octet. Cependant, vous pouvez accéder à 4 octets à la fois et travailler avec 4 octets à la fois au lieu d'un octet. Pour des vitesses plus élevées, vous pouvez utiliser pslldq (SSE2). Bien sûr, assurez-vous que les copies sont alignées pour une performance maximale.

+1

n'a rien à voir avec ce que le demandeur voulait. Il veut copier des données qui ont un alignement de sous-octets, vous lui dites simplement comment implémenter un «memcpy» pire que celui qu'il a déjà. – SamB

+2

@SamB: Pas vraiment. Bitshifting mots entiers à la fois sera beaucoup plus rapide que de le faire un octet à la fois. –

+0

oui - @R a raison. Beaucoup plus vite. vous pouvez regarder les cycles par instruction. Ne sautons pas aux conclusions des gens. – EdH

Questions connexes