He tenido que hacer esto muchas veces en el pasado, y nunca he estado satisfecho con los resultados.¿Qué es un algoritmo eficiente en el tiempo para copiar matrices de bits no alineadas?
¿Alguien puede sugerir una forma rápida de copiar una matriz de bits contigua desde el origen hasta el destino donde tanto la fuente como el destino pueden no estar alineados (desplazados a la derecha) en los límites convenientes del procesador?
Si la fuente y el destino no están alineados, el problema puede cambiarse rápidamente a uno en el que solo ninguno de ellos esté alineado (después de la primera copia).
Como punto de partida, mi código es inevitable que se busca algo así como las siguientes (ignorar los efectos no probados, lado esto es sólo una fuera el ejemplo manguito):
const char mask[8] = { 1, 3, 7, 15, 31, 63, 127, 255 };
/* Assume:
* - destination is already zeroed,
* - offsets are right shifts
* - bits to copy is big (> 32 say)
*/
int bitarray_copy(char * src, int src_bit_offset, int src_bit_len,
char * dst, int dst_bit_offset) {
if (src_bit_offset == dst_bit_offset) { /* Not very interesting */
} else {
int bit_diff_offset = src_bit_offset - dst_bit_offset; /* assume positive */
int loop_count;
char c;
char mask_val = mask[bit_diff_offset];
/* Get started, line up the destination. */
c = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
c &= mask[8-dst_bit_offset];
*dst++ |= c;
src_bit_len -= 8 - dst_bit_offset;
loop_count = src_bit_len >> 3;
while (--loop_count >= 0)
* dst ++ = (*src++ << bit_diff_offset) | ((*src >> (8 - bit_diff_offset)) & mask_val);
/* Trailing tail copy etc ... */
if (src_bit_len % 8) /* ... */
}
}
(en realidad esto es mejor que yo' he hecho antes. No se ve muy mal)
Use 'struct' (s) con campos de bits y deje que el compilador lo haga? : P –
* ¿Cómo * eso mejoraría las cosas? – Jamie
¿Se superponen estos campos de bits? ¿Puedes transformar el problema en un problema que se puede resolver simplemente aplicando memcpy? memcpy en Visual C++ está altamente optimizado (/ ARCH: SSE2), y GCC y sus amigos al menos se aseguran de que hayan alcanzado los límites de los párrafos antes de copiar grandes fragmentos. –