Der Martin: Bitweiser Zugriff

Beitrag lesen

Hallo Peter,

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.

wenn die Position des abzufragenden Bits schließlich auch noch variabel ist, kommt man fast nicht um eine Schiebeoperation herum - es sei denn, man verfolgt einen tabellenbasierten Ansatz:

$bitmask = Array(0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80);
 ...
 if ($foo & $bitmask[$botposition])
  { ... }

Ich glaube, hier ist PHP wirklich ein schlechtes Beispiel; als Scriptsprache, die erst zur Laufzeit interpretiert wird, sind solche Optimierungen da wohl ein Tropfen im Ozean. Aber in C oder Assembler würde ich diesen Ansatz für zeitkritische Routinen durchaus erwägen. Je nach Rechnerarchitektur kann das tatsächlich schneller sein als die Bitschieberei, denn eine indizierte Adressierung eines Arrays unterstützt jede mir bekannte CPU von sich aus.

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?

Siehe oben. ;-)

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.
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.

Das kann man nicht generell für alle Prozessoren sagen. Bei der klassischen Intel-Architektur ist aber der Zeitaufwand für eine Schiebeoperation tatsächlich proportional zur Anzahl der Bitpositionen.

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

Richtig. Gute Compiler erkennen aber Teilausdrücke, die nur aus Konstanten bestehen, und können aufwendige Terme dadurch oft dennoch etwas vereinfachen, wenn es der Progrmmierer nicht schon getan hat.

In Assembler auf jeden Fall, aber C ist nahe dran.
Bedeutet das, dass sich in Assembler Bits direkt "per Adresse" auslesen lassen, ...

Nein, bei den gängigen CPUs nicht. Die können nur ganze Bytes (Worte, Doppelworte) lesen und dann das gewünschte Bit mit einer UND-Verknüpfung isolieren. Womit wir wieder am Anfang wären. ;-)

Ciao,
 Martin

--
Schon gewusst, dass Aftershave trotz des Namens eigentlich eher fürs Gesicht gedacht ist?