Peter Thomassen: Bitweiser Zugriff

Beitrag lesen

Hallo Martin,

danke für deine Antwort.

$bit = $foo >> 5 & 1

für das 5. Bit von rechts.

Ja, das ist eine Möglichkeit; wenn man ein Bit testet, ist aber der exakte numerische Wert dieses Bits unerheblich, deswegen wird man in der Regel auf die Shift-Operation verzichten. Schließlich reicht es zu wissen, ob
$foo & 0x20
ungleich 0 ist.

Das klingt in der Tat elegant, allerdings besteht im konkreten Fall die Notwendigkeit, in einer Schleife mehrere Bits zu testen, die an verschiedener Position in verschiedenen Variablen stehen. Diese Fälle lassen sich schlecht explizit angeben.

Nun kann ich 0x20 entweder als Potenz von 2 oder per links-Shift herstellen, oder aber gleich das zu betrachtende Bit nach rechts schieben, wie es das obigen Codebeispiel tut. Oder gibt es hier eine bessere Vorgehensweise?

  • 5 Schritte für den Bitshift

Nein, selbst wenn man den Shift ausführen würde (was man meist bleiben lässt), ist das bei modernen CPUs nur ein einziger Schritt. Okay, mehrere Arbeitsschritte, aber nur eine Maschineninstruktion.

Interessieren würde mich der Zeitaufwand. Werden diese Arbeitsschritte parallel oder nacheinander ausgeführt (also Zeitkomplexität O(1) oder O(Bitzahl)? Ich muss zugeben, von Prozessorinterna keine Ahnung zu haben.

Normalerweise wird eine UND-Verknüpfung mit ALLEN Bits im Register parallel durchgeführt, also je nach Architektur 8, 16, 32 oder gar 64 Bits auf einmal.

Also konstanter Zeitaufwand.

Der Compiler erkennt solche Konstrukte und ersetzt sie durch einen direkten Zugriff auf das Bit. Zur Laufzeit ist das also 1 Schritt (unabhängig vom zu betrachtenden Bit).

Viele Compiler sind in der Tat so schlau, diesen Ausdruck zu optimieren.

Das scheint aber im oben beschriebenen Fall nicht möglich, wenn nicht konkret $foo >> 5 geshiftet wird, sondern $foo >> $i oder so.

In welchen Programmiersprachen ist ein solcher direkter Zugriff (entweder per Adressierung im Programmoce oder durch die Compiler-Optimierung) möglich? Ist das überhaupt möglich?

In Assembler auf jeden Fall, aber C ist nahe dran.

Bedeutet das, dass sich in Assembler Bits direkt "per Adresse" auslesen lassen, wie üblicherweise Variablen auch, d.h. ohne es mit 1 zu vergleichen?

Bye,
Peter