Les opérations au niveau du bit sont absolument essentielles lors de la programmation des registres matériels dans les systèmes embarqués. Par exemple, chaque processeur que j'ai jamais utilisé possède un ou plusieurs registres (généralement une adresse mémoire spécifique) qui contrôlent si une interruption est activée ou désactivée. Pour permettre à une interruption de se déclencher, le processus habituel consiste à définir le bit d'activation pour ce type d'interruption tout en ne modifiant surtout aucun des autres bits du registre.
Lorsqu'une interruption se déclenche, elle définit généralement un bit dans un registre d'état afin qu'une seule routine de service puisse déterminer la raison précise de l'interruption. Le test des bits individuels permet un décodage rapide de la source d'interruption.
Dans de nombreux systèmes embarqués, la RAM totale disponible peut être de 64, 128 ou 256 octets (c'est-à-dire des octets et non des kilo-octets ou des mégaoctets). Dans cet environnement, il est courant d'utiliser un octet pour stocker plusieurs éléments de données, drapeaux booléens, etc., puis d'utiliser des opérations sur les bits pour définir et lire ces derniers.
Je travaille depuis plusieurs années avec un système de communication par satellite dont la charge utile de message est de 10,5 octets. Pour tirer le meilleur parti de ce paquet de données, les informations doivent être regroupées dans le bloc de données sans laisser de bits inutilisés entre les champs. Cela signifie faire un usage intensif des opérateurs au niveau du bit et du décalage pour prendre les valeurs d'information et les empaqueter dans la charge utile transmise.
Fondamentalement, vous les utilisez en raison de considérations de taille et de vitesse. Les opérations au niveau du bit sont incroyablement simples et donc généralement plus rapides que les opérations arithmétiques. Par exemple, pour obtenir la partie verte d'une valeur RVB, l'approche arithmétique est
(rgb / 256) % 256
. Avec des opérations au niveau du bit, vous feriez quelque chose comme(rgb >> 8) & 0xFF
. Ce dernier est beaucoup plus rapide et une fois que vous y êtes habitué, c'est aussi plus facile. Généralement, les opérations au niveau du bit entrent en jeu lorsque vous devez encoder / décoder des données de manière compacte et rapide.la source
BYTE g1 = (rgb / 256) % 256;
00E51013...C1 E9 08...shr ecx,8
00E51016...88 0C 24...mov byte ptr [esp],cl
Ce type d'opérations est souvent utilisé lors de l'écriture pour les systèmes embarqués où la mémoire ou la puissance du processeur sont limitées.
Par exemple, pour économiser de l'espace, vous pouvez stocker plusieurs variables dans une seule variable int 8 bits en utilisant chaque bit pour représenter un booléen. Ensuite, vous avez besoin d'un moyen rapide pour définir un bit spécifique ou récupérer la valeur du bit.
Généralement, lors de la programmation dans des langages de niveau supérieur comme C # sur un ordinateur de bureau avec des gigaoctets de mémoire, vous ne vous souciez pas vraiment que chacun
bool
occupe un octet entier . Mais si vous programmez un microcontrôleur en C avec 2 Ko de mémoire, chaque bit compte, donc la possibilité de regrouper 8 bools en un seul octet peut être critique.la source
[Flags]
attribut qui permet d'utiliser unEnum
champ en tant que bit. Par exemple,Font
possède uneStyle
propriété qui est un champ de bits contenant des caractères gras, italique, souligné et barré.Les opérations au niveau du bit sont également fréquemment utilisées dans les codecs vidéo et audio, pour la même raison que dans l'électronique embarquée; être capable d'emballer cinq drapeaux et un minuteur de onze bits dans un demi-entier est très utile lorsque vous voulez créer un codec vidéo super efficace.
En fait, MPEG 4 utilise même un codage exponentiel de Golomb pour les champs de longueur variable. Une valeur qui était de 17 ou 19 bits de large dernier paquet pourrait avoir seulement trois ou cinq bits de large ce paquet - et vous comprendrez tout cela avec des opérations au niveau du bit.
la source
Les astuces qui combinent des opérations logiques au niveau du bit, des opérations de décalage au niveau du bit et des opérations arithmétiques peuvent être comprises par les personnes qui ont étudié la construction d'un additionneur binaire à l'aide de portes logiques (et, ou, non). En dehors de ce cercle, il est très difficile de comprendre sans un commentaire détaillé.
Il est utile lors de la programmation d' unités SIMD , surtout si l'architecture du processeur a intentionnellement omis certaines instructions SIMD car elles pourraient être émulées par quelques autres.
Par exemple, l'architecture peut ne pas définir d'instructions pour prendre les valeurs négatives d'un groupe de 16 octets, mais cela peut être émulé par la négation au niveau du bit puis en ajoutant 1. De même, la soustraction peut également être omise, car elle peut être émulée en prenant le négatif du deuxième opérande. La disponibilité de la "route alternative" est la raison de l'omission de certaines instructions.
De même, le SIMD peut uniquement prendre en charge l'ajout parallèle 8 bits, sans implémenter l'ajout pour des éléments plus larges tels que 16 bits, 32 bits ou 64 bits. Pour les émuler, il faut extraire le bit de signe du résultat du calcul à 8 bits, puis effectuer l'opération de report sur l'élément suivant.
la source
Emballage des données, opérations plus rapides (multiplication, division et module sont beaucoup plus rapides s'ils sont alignés sur des puissances de 2), retournement de bits, etc. Apprenez-les et commencez à les utiliser et vous commencerez lentement à voir la plupart des avantages par vous-même.
la source