Lectura en la memoria de PIC32MX en C y XORing grandes conjuntos de datos

Tengo un proyecto en el que tengo 102 registros de desplazamiento PISO de 8 bits en configuración de cadena de margarita y están saliendo a una línea SDI común conectada a un controlador PIC32MX.

Hay un total de 816 bits que necesito leer y almacenar en la memoria para poder manipular los datos que se leen. Además, tendré que leerlos 34 veces porque la aplicación requiere que haga XOR en esos 816 bits para cada una de estas operaciones de lectura.

Tengo dos preguntas:

  • ¿Cómo almacenarías los datos? Estoy preocupado porque tendré que manejar bastantes datos y estoy tratando de optimizar el procesamiento al mínimo. Tenga en cuenta que necesito poder extraer los índices (fila, columna) para poder calcular otros valores en consecuencia.
  • Después de XORing los datos, tendré que atravesar la estructura y encontrar ocurrencias de '0'. ¿Qué sugieres en términos de algoritmo de búsqueda?

Estaba pensando en crear una matriz con una dimensión [34,816] y XOR secuencialmente las filas en una sola matriz de 816 columnas y luego buscar '0' en la matriz, pero no estoy seguro de cómo hacerlo, ¿alguna idea?

Entonces, ¿tienes 102 líneas CS? Esto suena más como un problema de programación general no relacionado con el diseño electrónico. Recomiendo que se mueva a stackoverflow.com , donde puede obtener mejores consejos sobre algoritmos.
@tcrosley, tiendo a estar de acuerdo, aunque decidí publicarlo aquí debido a las implicaciones de programar en una arquitectura PIC. ¿Cómo podría mover la pregunta allí?
Todos los registros de desplazamiento dan salida a la misma línea, un bit a la vez. Selecciono qué registro de desplazamiento está activo en cada momento con contadores Johnson. Estaré leyendo desde un solo pin, pero ese no es mi problema, el manejo de la memoria y el algoritmo de búsqueda son... :)
Solo tenía curiosidad por los CS. Marqué esto para llamar la atención del moderador.
Creo que esta pregunta está lo suficientemente ligada a la programación integrada que debería permanecer ahí por ahora.

Respuestas (1)

Para procesar los bits de la manera más eficiente posible, querrá mantenerlos empaquetados en palabras de 32 bits donde sea que tenga sentido. 816 bits son 25,5 palabras, lo que no está nada mal.

Para buscar los unos de manera eficiente, divida la tarea en dos pasos: verifique palabras enteras que no sean cero en el ciclo externo, luego busque bits individuales en las palabras que no sean todos cero en el ciclo interno.

Un truco que se puede usar para aislar bits individuales en una palabra que tiene varios bits establecidos es Y la palabra con su negación (complemento a 2). El resultado tiene solo un conjunto de bits: el 'uno' más a la derecha en la palabra original. Luego puede usar este resultado para borrar ese bit y buscar el siguiente 'uno'.

Cª:

temp = word & -word;
word &= ~temp;

Por ejemplo, suponga que su palabra de 32 bits contiene 0x40010080:

01000000000000010000000010000000  original word
10111111111111101111111110000000  ... negated
00000000000000000000000010000000  ... and then ANDed together

11111111111111111111111101111111  complement of previous word
01000000000000010000000000000000  ... ANDed with original word for next iteration

EDITAR:

La eficiencia de este algoritmo proviene del hecho de que solo itera una vez para cada 'uno' (tres de ellos en este ejemplo), en lugar de una vez para cada uno de los 32 bits de la palabra. Esta es una gran ventaja si estás haciendo algo como simplemente contar los 'unos'. La desventaja es que no le proporciona el índice de bits directamente, pero también hay formas de acelerarlo. Por ejemplo, para obtener el índice de bits de un solo bit establecido en una palabra, podría usar un algoritmo de codificación binaria:

index = 0;
if (word & 0xAAAAAAAA) index += 1;
if (word & 0xCCCCCCCC) index += 2;
if (word & 0xF0F0F0F0) index += 4;
if (word & 0xFF00FF00) index += 8;
if (word & 0xFFFF0000) index += 16;

La ventaja general de los dos algoritmos anteriores, en comparación con una iteración de fuerza bruta a través de los bits, depende de cuántos bits espera encontrar en cada palabra. Si son raros (menos de 4 por palabra), entonces estos algoritmos deberían ser más rápidos. Si son más comunes que eso, simplemente vaya con el bucle iterativo:

for (index = 0, mask = 0x00000001; index < 32; ++index, mask <<= 1) {
  if (word & mask) {
    /* do your processng here */
  }
}
Lo siento, pero no pude seguirte con respecto a tu último párrafo (no soy un hablante nativo de inglés). ¿Puedes elaborar?
¡Gracias por su rápida respuesta! Entendí lo que quisiste decir ahora, pero todavía no entiendo cómo esto agrega eficiencia. ¿Realmente necesito esta operación? Estaba pensando en simplemente calcular el índice (hasta 816) si el valor de una determinada palabra de 32 bits fuera mayor que 0, ¿no crees que es más rápido?
Además, quise decir encontrar '0's no '1's.
Para encontrar ceros, aún puede usar este algoritmo, simplemente invierta los datos primero (o, si los datos con los que está haciendo XOR son fijos, simplemente invierta eso ). La eficiencia de este algoritmo proviene del hecho de que solo itera una vez para cada 'uno' (tres de ellos en este ejemplo), en lugar de una vez para cada uno de los 32 bits de la palabra. Esta es una gran ventaja si estás haciendo algo como simplemente contar los 'unos'. La desventaja es que no le proporciona el índice de bits directamente, pero también hay formas de acelerarlo. ¿Vas a programar en C o ensamblador?
¡Gracias de nuevo por tu ayuda! Estaré programando en C. ¿Puede compartir alguna idea sobre cómo implementaría dicho algoritmo?
Ver mi edición de arriba.
¡Señor, me siento honrado por sus enseñanzas! ¡Muchas felicitaciones! :)