Eine schlauere Art, aus dem Array von Bits zu extrahieren?

8

Ich habe Speicherbereiche, die man als "Array of Bits" bezeichnen könnte. Sie sind äquivalent zu

%Vor%

Aber es wäre besser als

gedacht %Vor%

Ich greife mit

auf separate Bits davon zu %Vor%

Aber ich mache es oft an vielen Stellen des Codes, oft in performancekritischen Abschnitten, und ich frage mich, ob es intelligentere, optimalere Methoden dafür gibt.

Zusatzinfo: Architektur: ARM9 (32 Bit); gcc / Linux. Die physische Datendarstellung kann nicht geändert werden - sie wird extern bereitgestellt oder für die externe Verwendung zugeordnet.

    
SF. 29.01.2010, 08:29
quelle

8 Antworten

6

Für den zufälligen Zugriff auf einzelne Bits ist das von Ihnen vorgeschlagene Makro so gut, wie Sie es erhalten werden (solange Sie Optimierungen in Ihrem Compiler aktivieren).

Wenn für die Bits, auf die Sie zugreifen, überhaupt ein Muster vorhanden ist, können Sie möglicherweise bessere Ergebnisse erzielen. Wenn Sie beispielsweise oft auf Paare von Bits zugreifen, sehen Sie möglicherweise eine Verbesserung, indem Sie eine Methode bereitstellen, um zwei statt eins zu erhalten, auch wenn Sie nicht immer beide Bits verwenden.

Wie bei jedem Optimierungsproblem müssen Sie sich mit dem Verhalten Ihres Codes, insbesondere mit den Zugriffsmustern in Ihrem Bit-Array, sehr gut auskennen, um die Leistung erheblich zu verbessern.

Aktualisieren : Da Sie auf Bereiche von Bits zugreifen, können Sie wahrscheinlich etwas mehr Leistung aus Ihren Makros herausholen. Wenn Sie beispielsweise auf vier Bits zugreifen müssen, haben Sie möglicherweise Makros wie folgt:

%Vor%

Diese Makros würden vier Bits von jeder Bitposition 0, 1, 2, usw. ausschneiden. (Um die Zunahme von sinnlosen Klammern zu reduzieren, können Sie Inline-Funktionen für das obige verwenden.) Dann definieren Sie vielleicht ein Inline Funktion wie:

%Vor%

Da dies eine Menge langweiligen Standardcode ist, besonders wenn Sie mehrere verschiedene Breiten haben, möchten Sie vielleicht ein Programm schreiben, um alle GETBIT_* Accessor-Funktionen zu generieren.

(Ich bemerke, dass die Bits in Ihren Bytes in der umgekehrten Reihenfolge von dem, was ich oben geschrieben habe, gespeichert werden. Wenden Sie eine geeignete Umwandlung an, um Ihrer Struktur zu entsprechen, wenn Sie das müssen.)

    
Greg Hewgill 29.01.2010, 08:40
quelle
7

Ich glaube nicht. Tatsächlich greifen viele CPU-Architekturen nicht einzeln auf Bits zu.

In C ++ haben Sie std::bitset<N> . kann jedoch abhängig von der Implementierung und Optimierung Ihres Compilers nicht die höchste Leistung aufweisen.

Übrigens, es ist vielleicht besser, Ihr Bit-Array als uint32_t[32] (oder uint64_t[16] ) für die ausgerichtete Dereferenzierung zu gruppieren (was bitset dies bereits für Sie tut).

    
kennytm 29.01.2010 08:39
quelle
3

Nehmen wir Gregs Lösung als Grundlage:

%Vor%

Kann mindestens 32 Bits erhalten, auch wenn sie nicht ausgerichtet sind. Beachten Sie, dass absichtlich inline ist, da Sie nicht viele dieser Funktionen haben möchten.

    
MSalters 29.01.2010 09:27
quelle
1

Wenn Sie die Bit-Reihenfolge in 'arr' umkehren, können Sie die Subtraktion aus dem Makro entfernen. Es ist das Beste, was ich sagen kann, ohne Kenntnis des Problemkontexts (wie die Bits verwendet werden).

    
sambowry 29.01.2010 08:37
quelle
1
%Vor%

kann optimiert werden.

1) Verwenden Sie das Standard-Int, das normalerweise der am schnellsten zugängliche Ganzzahl-Datentyp ist.    Wenn Sie nicht tragbar sein müssen, können Sie die Größe eines int mit herausfinden    sizeof und passen Sie den folgenden Code an.

2)

%Vor%

Der Mod-Operator% ist langsamer als ANDing. Und Sie müssen nicht subtrahieren, Passe einfach deine SETBIT-Routine an.

    
Thorsten S. 29.01.2010 09:07
quelle
0

Warum erstellen Sie nicht Ihre eigene Wrapper-Klasse?

Sie könnten dann mit einem Operator wie + Bits zum "Array" hinzufügen und die einzelnen Bits mit dem Operator [] zurückholen.

Ihr Makro könnte verbessert werden, indem Sie & amp; 7 statt% 8, aber wahrscheinlich wird der Compiler diese Optimierung sowieso für Sie vornehmen.

Ich habe kürzlich genau das getan, was Sie tun, und mein Stream könnte aus einer beliebigen Anzahl von Bits bestehen.

Also habe ich etwas wie das Folgende:

%Vor%

und so weiter. Es macht schön lesbaren Code und Sie können eine STL-ähnliche Schnittstelle zur Unterstützung der Ähnlichkeit zur Verfügung stellen:)

    
Goz 29.01.2010 08:38
quelle
0

Da die Frage mit C ++ markiert ist, gibt es einen Grund, warum Sie nicht einfach das Standard-Bitset verwenden können ?

    
Max Shawabkeh 29.01.2010 08:41
quelle
0

Anstelle des unsignierten char-Arrays und der benutzerdefinierten Makros können Sie std::vector<bool> verwenden. Die Vektorklassenvorlage hat eine spezielle Template-Spezialisierung für den Bool-Typ. Diese Spezialisierung wird bereitgestellt, um die Speicherplatzzuweisung zu optimieren: Bei dieser Vorlagenspezialisierung belegt jedes Element nur ein Bit (was acht Mal weniger ist als der kleinste Typ in C ++: char).

    
Vijay Mathew 29.01.2010 09:44
quelle