Was sind die Vorteile von bitweisen Operationen? [geschlossen]


19

Nachdem ich den neuesten CodeProject-Newsletter gelesen hatte, stieß ich auf diesen Artikel über bitweise Operationen . Es ist interessant zu lesen, und ich kann mit Sicherheit den Vorteil erkennen, zu prüfen, ob eine Ganzzahl gerade oder ungerade ist, aber zu prüfen, ob das n-te Bit gesetzt ist. Was können die Vorteile davon sein?

Antworten:


27

Bitweise Operationen sind beim Programmieren von Hardwareregistern in eingebetteten Systemen unbedingt erforderlich. Zum Beispiel hat jeder Prozessor, den ich jemals benutzt habe, ein oder mehrere Register (normalerweise eine bestimmte Speicheradresse), die steuern, ob ein Interrupt aktiviert oder deaktiviert ist. Damit ein Interrupt ausgelöst werden kann, muss das Aktivierungsbit für diesen einen Interrupttyp gesetzt werden, wobei vor allem keines der anderen Bits im Register geändert werden darf.

Wenn ein Interrupt ausgelöst wird, setzt er normalerweise ein Bit in einem Statusregister, sodass eine einzelne Serviceroutine den genauen Grund für den Interrupt bestimmen kann. Das Testen der einzelnen Bits ermöglicht ein schnelles Dekodieren der Interruptquelle.

In vielen eingebetteten Systemen kann der insgesamt verfügbare RAM 64, 128 oder 256 Byte betragen (dh Bytes, nicht Kilobytes oder Megabytes). In dieser Umgebung wird häufig ein Byte verwendet, um mehrere Datenelemente, Boolesche Flags usw. zu speichern und anschließend Bitoperationen zu verwenden um diese zu setzen und zu lesen.

Ich arbeite seit einigen Jahren mit einem Satellitenkommunikationssystem, bei dem die Nachrichtennutzlast 10,5 Bytes beträgt. Um dieses Datenpaket optimal zu nutzen, müssen die Informationen in den Datenblock gepackt werden, ohne dass nicht verwendete Bits zwischen den Feldern verbleiben. Dies bedeutet, dass bitweise Operatoren und Shift-Operatoren ausgiebig verwendet werden, um die Informationswerte in die zu übertragende Nutzlast zu packen.


4
Für diejenigen, die an mehr booleschen Bitoperationen und Optimierungen interessiert sind, werfen Sie einen Blick auf Hacker's Delight: amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201914654
gablin 22.10.10

7

Grundsätzlich verwenden Sie sie aus Gründen der Größe und Geschwindigkeit. Bitweise Operationen sind unglaublich einfach und daher normalerweise schneller als arithmetische Operationen. Um beispielsweise den grünen Teil eines RGB-Werts zu erhalten, lautet der arithmetische Ansatz (rgb / 256) % 256. Mit bitweisen Operationen würden Sie etwas wie tun (rgb >> 8) & 0xFF. Letzteres ist deutlich schneller und wenn Sie sich erst einmal daran gewöhnt haben, ist es auch einfacher. Im Allgemeinen spielen bitweise Operationen eine große Rolle, wenn Sie Daten kompakt und schnell codieren / decodieren müssen.


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

4

Diese Art von Operationen wird häufig beim Schreiben für eingebettete Systeme verwendet, bei denen der Arbeitsspeicher oder die CPU-Leistung eingeschränkt sind.

Um beispielsweise Platz zu sparen, können Sie mehrere Variablen in einer einzelnen 8-Bit-Int-Variablen speichern, indem Sie jedes Bit zur Darstellung eines Booleschen Werts verwenden. Dann brauchen Sie einen schnellen Weg, um ein bestimmtes Bit zu setzen oder den Bitwert abzurufen.

Im Allgemeinen ist es beim Programmieren in höheren Programmiersprachen wie C # auf einem Desktop-PC mit Gigabyte Arbeitsspeicher nicht wichtig, dass jedes bool ein ganzes Byte belegt . Wenn Sie jedoch einen Mikrocontroller in C mit 2 KB Arbeitsspeicher programmieren, zählt jedes einzelne Bit. Daher kann die Fähigkeit, 8 Bools in ein einzelnes Byte zu packen, von entscheidender Bedeutung sein.


.NET hat das [Flags]Attribut, das die Verwendung eines EnumFeldes als Bit ermöglicht. Hat beispielsweise Fonteine StyleEigenschaft, die ein Bitfeld ist, das fett, kursiv, unterstrichen und durchgestrichen ist.
Extrem

@deltreme. Ja, ich weiß, dass Sie [Flags] verwenden können, aber darum geht es nicht. Der Punkt ist, dass Sie in Hochsprachen nicht viel Wert darauf legen, ein paar Bytes Platz für ein paar Bools zu verbrauchen. Im Allgemeinen legen Sie mehr Wert auf Wartbarkeit und Lesbarkeit des Codes. In eingebetteten Systemen, in denen Sie sich für die Größe interessieren, haben Sie keinen Zugriff auf Dinge wie das Attribut .net [Flags]. In diesem Fall können Sie diese bitweisen Operationen verwenden.
Simon P Stevens

"aber testen, ob das n-te Bit gesetzt ist? Was können die Vorteile davon sein?" So ist es der Punkt - aber da keine Sprache angegeben wurde, habe ich beschlossen, es als Kommentar zu einer Antwort einzugeben, in der C # erwähnt wurde. Es ist kein Kommentar zu Ihrer Antwort, es ist eine Ergänzung, oder gut zu wissen, oder was auch immer.
Deltreme

@deltreme: Oh, cool.
Simon P Stevens

3

Bitweise Operationen werden auch häufig in Video- und Audio-Codecs verwendet, aus demselben Grund wie in eingebetteter Elektronik. Die Möglichkeit, fünf Flags und einen Elf-Bit-Timer in einen halben Int zu packen, ist sehr nützlich, wenn Sie einen supereffizienten Videocodec erstellen möchten.

MPEG 4 verwendet sogar die exponentielle Golomb-Codierung für Felder mit variabler Bitlänge. Ein Wert, der als letztes Paket 17 oder 19 Bit breit war, könnte in diesem Paket nur drei oder fünf Bit breit sein - und Sie würden das alles mit bitweisen Operationen herausfinden.


2

Tricks, die bitweise logische Operationen, bitweise Verschiebungsoperationen und arithmetische Operationen kombinieren, können von Personen verstanden werden, die die Konstruktion eines binären Addierers unter Verwendung von Logikgattern studiert haben (und / oder nicht). Außerhalb dieses Kreises ist es ohne einen detaillierten Kommentar sehr schwer zu verstehen.

Dies ist nützlich, wenn Sie SIMD- Einheiten programmieren , insbesondere wenn die CPU-Architektur absichtlich einige SIMD-Anweisungen ausgelassen hat, da sie von einigen anderen emuliert werden könnten.

Beispielsweise definiert die Architektur möglicherweise keine Anweisungen zum Aufnehmen der negativen Werte einer Gruppe von 16 Bytes, die jedoch durch bitweises Negieren und anschließendes Addieren von 1 emuliert werden können. Ebenso kann auch eine Subtraktion weggelassen werden, da sie durch Aufnehmen emuliert werden kann das Negativ des zweiten Operanden. Die Verfügbarkeit der "Alternativroute" ist der Grund für das Weglassen bestimmter Anweisungen.

Ebenso unterstützt die SIMD möglicherweise nur eine parallele 8-Bit-Addition, ohne eine Addition für breitere Elemente wie 16-Bit, 32-Bit oder 64-Bit zu implementieren. Um sie zu emulieren, muss man das Vorzeichenbit aus dem 8-Bit-Berechnungsergebnis extrahieren und dann die Übertragoperation für das nächste Element ausführen.


0

Packen von Daten, schnellere Operationen (Multiplikation, Division und Modul sind bei Potenzen von 2 wesentlich schneller), Bit-Flipping usw. Lernen Sie sie und beginnen Sie, sie zu verwenden, und Sie werden langsam beginnen, die meisten Vorteile auf eigene Faust zu erkennen.


1
Das ist eine recht orthogonale Antwort.
itsbruce
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.