Per accedere in modo casuale a singoli bit, la macro che hai suggerito è buona come quella che otterrai (a patto di attivare le ottimizzazioni nel compilatore).
Se c'è qualche modello per i bit a cui si sta accedendo, allora si potrebbe essere in grado di fare meglio. Ad esempio, se accedi spesso alle coppie di bit, potresti notare dei miglioramenti fornendo un metodo per ottenere due bit invece di uno, anche se non sempre finisci con l'utilizzare entrambi i bit.
Come per qualsiasi problema di ottimizzazione, è necessario avere molta familiarità con il comportamento del codice, in particolare i suoi schemi di accesso nel proprio array di bit, per ottenere un miglioramento significativo delle prestazioni.
Aggiornamento: Poiché si accede a intervalli di bit, è possibile probabilmente ottenere un po 'più di prestazioni dai propri macro. Ad esempio, se è necessario accedere a quattro bit si potrebbe avere le macro come questo:
#define GETBITS_0_4(x,in) (((in)[(x)/8] & 0x0f))
#define GETBITS_1_4(x,in) (((in)[(x)/8] & 0x1e) >> 1)
#define GETBITS_2_4(x,in) (((in)[(x)/8] & 0x3c) >> 2)
#define GETBITS_3_4(x,in) (((in)[(x)/8] & 0x78) >> 3)
#define GETBITS_4_4(x,in) (((in)[(x)/8] & 0xf0) >> 4)
#define GETBITS_5_4(x,in) ((((in)[(x)/8] & 0xe0) >> 5) | (((in)[(x)/8+1] & 0x01)) << 3)
#define GETBITS_6_4(x,in) ((((in)[(x)/8] & 0xc0) >> 6) | (((in)[(x)/8+1] & 0x03)) << 2)
#define GETBITS_7_4(x,in) ((((in)[(x)/8] & 0x80) >> 7) | (((in)[(x)/8+1] & 0x07)) << 1)
// ...etc
Queste macro avrebbero ritagliare quattro bit da ogni posizione di bit 0, 1, 2, ecc (Per ridurre la proliferazione di parentesi inutili, si potrebbe desiderare di utilizzare funzioni inline per quanto sopra) Allora, forse, definire una funzione inline, come:.
inline int GETBITS_4(int x, unsigned char *in) {
switch (x % 8) {
case 0: return GETBITS_0_4(x,in);
case 1: return GETBITS_1_4(x,in);
case 2: return GETBITS_2_4(x,in);
// ...etc
}
}
Poiché si tratta di un sacco di codice boilerplate noioso, soprattutto se hai più diverse larghezze , potresti voler scrivere un programma per generare tutte le funzioni di accesso GETBIT_*
.
(ho notato che i bit nei vostri byte vengono memorizzati in ordine inverso da quello che ho scritto sopra. Applicare una trasformazione appropriata per abbinare la struttura se è necessario.)
So che c'è una variazione nel numero di bit per char, ma 256 bit per char è uno _lot_. – MSalters
MSalters: grazie, risolto. –