Quali sono i vantaggi dell'utilizzo delle operazioni bit a bit? [chiuso]


19

Dopo aver letto l'ultima newsletter di CodeProject, mi sono imbattuto in questo articolo sulle operazioni bit per bit . Rende interessante la lettura, e posso certamente vedere il vantaggio di verificare se un numero intero è pari o dispari, ma verificare se è impostato l'n-esimo bit? Quali possono essere i vantaggi di questo?

Risposte:


27

Le operazioni bit per bit sono assolutamente essenziali durante la programmazione dei registri hardware nei sistemi embedded. Ad esempio, ogni processore che io abbia mai usato ha uno o più registri (di solito un indirizzo di memoria specifico) che controllano se un interrupt è abilitato o disabilitato. Per consentire l'attivazione di un interrupt, il normale processo consiste nell'impostare il bit di abilitazione per quel tipo di interrupt, ma soprattutto, non modificando nessuno degli altri bit nel registro.

Quando viene generato un interrupt, in genere imposta un bit in un registro di stato in modo che una singola routine di servizio possa determinare il motivo preciso dell'interrupt. Il test dei singoli bit consente una decodifica rapida della sorgente di interrupt.

In molti sistemi embedded la RAM totale disponibile può essere 64, 128 o 256 BYTES (ovvero byte non kilobyte o megabyte) In questo ambiente è comune utilizzare un byte per memorizzare più elementi di dati, flag booleani ecc. E quindi utilizzare operazioni a bit per impostare e leggere questi.

Per diversi anni ho lavorato con un sistema di comunicazione satellitare in cui il payload del messaggio è di 10,5 byte. Per utilizzare al meglio questo pacchetto di dati, le informazioni devono essere inserite nel blocco dati senza lasciare bit inutilizzati tra i campi. Ciò significa fare ampio uso degli operatori bit per bit e shift per acquisire i valori delle informazioni e impacchettarli nel payload da trasmettere.


4
Per coloro che sono interessati a operazioni e ottimizzazioni di bit più booleani, dai un'occhiata a Hacker's Delight: amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201914654
gablin

7

Fondamentalmente, li usi a causa di considerazioni su dimensioni e velocità. Le operazioni bit a bit sono incredibilmente semplici e quindi solitamente più veloci delle operazioni aritmetiche. Ad esempio, per ottenere la parte verde di un valore rgb, l'approccio aritmetico è (rgb / 256) % 256. Con operazioni bit per bit faresti qualcosa come (rgb >> 8) & 0xFF. Quest'ultimo è significativamente più veloce e una volta che ci sei abituato, è anche più facile. In genere le operazioni bit a bit entrano in gioco quando è necessario codificare / decodificare i dati in modo compatto e veloce.


2
BYTE g1 = (rgb / 256) % 256; 00E51013...C1 E9 08...shr ecx,8 00E51016...88 0C 24...mov byte ptr [esp],cl
rwong,

4

Questo tipo di operazioni vengono spesso utilizzate quando si scrive per sistemi embedded in cui la memoria o la potenza della CPU sono limitate.

Ad esempio, per risparmiare spazio è possibile memorizzare più variabili in una singola variabile int a 8 bit utilizzando ciascun bit per rappresentare un valore booleano. Quindi è necessario un modo rapido per impostare un bit specifico o recuperare il valore del bit.

Generalmente quando si programma in linguaggi di livello superiore come C # su un PC desktop con Gigabyte di memoria, non ti interessa davvero che ognuno bool occupi un intero byte . Ma se stai programmando un microcontrollore in C con 2kb di memoria, ogni singolo bit conta, quindi la capacità di impacchettare 8 bool in un singolo byte può essere critica.


.NET ha l' [Flags]attributo che consente di utilizzare un Enumcampo come bit. Ad esempio, Fontha una Styleproprietà che è un campo bit contenente grassetto, corsivo, sottolineato e barrato.
deltreme,

@deltreme. Sì, lo so che puoi usare [Flags], ma non è questo il punto. Il punto è che nelle lingue di alto livello non ti interessa molto l'utilizzo di pochi byte di spazio per un paio di bool. In genere ti preoccupi di più della manutenibilità e della leggibilità del codice. Nei sistemi embedded in cui tieni alle dimensioni, non hai accesso a cose come l'attributo .net [Flags], quindi è qui che puoi usare queste operazioni bit a bit.
Simon P Stevens,

"ma test se è impostato l'n-esimo bit? Quali possono essere i vantaggi di questo?" quindi è questo il punto - ma poiché non è stata specificata alcuna lingua, ho deciso di inserirlo come commento su una risposta in cui è stato menzionato C #. Non è un commento sulla tua risposta, è un'aggiunta, o piacevole da sapere, o altro.
deltreme,

@deltreme: Oh, bello.
Simon P Stevens,

3

Le operazioni bit a bit vengono anche utilizzate frequentemente nei codec video e audio, per lo stesso motivo dell'elettronica incorporata; essere in grado di impacchettare cinque flag e un timer a undici bit in mezzo int è molto utile quando si desidera creare un codec video super efficiente.

In effetti, MPEG 4 utilizza persino la codifica esponenziale di Golomb per campi a lunghezza di bit variabile. Un valore di 17 o 19 bit di larghezza nell'ultimo pacchetto potrebbe essere largo solo tre o cinque bit in questo pacchetto - e lo capiresti con operazioni bit per bit.


2

I trucchi che combinano operazioni logiche bit a bit, operazioni a turni bit a bit e operazioni aritmetiche possono essere compresi da persone che hanno studiato la costruzione di un sommatore binario usando porte logiche (e, o no). Al di fuori di quel cerchio, è molto difficile da capire senza un commento dettagliato.

È utile durante la programmazione di unità SIMD , soprattutto se l'architettura della CPU ha intenzionalmente tralasciato alcune istruzioni SIMD perché potrebbero essere emulate da pochi altri.

Ad esempio, l'architettura potrebbe non definire alcuna istruzione per prendere i valori negativi di un gruppo di 16 byte, ma che può essere emulata negando bit per bit e quindi aggiungendo 1. Allo stesso modo, anche la sottrazione può essere omessa, perché può essere emulata prendendo il negativo del secondo operando. La disponibilità del "percorso alternativo" è la ragione per omettere determinate istruzioni.

Allo stesso modo, il SIMD può supportare solo l'aggiunta parallela a 8 bit, senza implementare l'aggiunta per elementi più ampi come 16-bit, 32-bit o 64-bit. Per emularli, è necessario estrarre il bit del segno dal risultato del calcolo a 8 bit, quindi eseguire l'operazione carry sull'elemento successivo.


0

Dati di imballaggio, operazioni più rapide (moltiplicazione, divisione e modulo sono significativamente più veloci se allineati a potenze di 2), lanci di bit, ecc. Imparali e inizia a usarli e inizierai lentamente a vedere la maggior parte dei vantaggi da solo.


1
Questa è una risposta piuttosto ortogonale.
itsbruce
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.