Was Sie sehen, ist der klassische Zeit-Speicher-Kompromiss. Die Bitfelder sind im Speicher kleiner, benötigen jedoch mehr Zeit für die Bearbeitung. Sie können zählen, dass die Bitfelder unabhängig vom Prozessor langsamer sind.
Sie verwenden das Wort effizient , aber dieses Wort hat keine bestimmte Bedeutung ohne eine Metrik für das, was gut oder schlecht ist. Wenn Sie nur 8 KB RAM haben und die Verwendung des Speichers schlecht ist, kann die Zeit günstig sein. Wenn Sie Echtzeitbeschränkungen haben, ist die Verwendung von Zeit schlecht und der Speicher kann billig sein. Im Allgemeinen können Sie sich nur aus diesem Kompromiss herauskaufen. Mit anderen Worten, wenn Sie Zeit und Gedächtnis schlecht finden, geben Sie Geld aus und verwenden Sie einen größeren Chip. Es gibt keine einheitliche Antwort auf das, was gut oder schlecht ist. Dies ist einer der Gründe, warum es für Mikrocontroller so viele Möglichkeiten gibt, dass Menschen den Chip an die Anwendung und die Anwendung an den Chip anpassen.
Das Auffüllen der Bits eines Bitfelds ist langsamer als das Füllen vollständiger Bytes. Nehmen wir zum Beispiel
x = 5;
...
asimplestruct.len = x;
// vs
abitfield.len = x;
Der erste einfache Fall wird nur:
- Lade den Wert von x in ein Register
- Speichern Sie es im Byte für len
Der zweite macht so etwas wie:
- Lädt den aktuellen Wert von abitfield
- lädt eine Maske
- löscht die Bits für len
- lädt den aktuellen Wert von x
- lädt eine Maske
- löscht nicht verwendete Bits von x
- verschiebt die Bits von x
- oder ist x mit dem abitfield
- speichert den aktuellen Wert zurück im Speicher
Wenn alle Ihre Vorgänge Daten in das Bitfeld packen oder aus dem Bitfeld entpacken, sollten Sie mit einer langsameren Ausführung rechnen. Bitfelder sind eine Art Komprimierung - sie kosten Ticks.
Das Bewegen in Bitfeldern ist jedoch schneller, da weniger Bytes geladen und gespeichert werden müssen. Wenn Sie dieses Array sortieren, kann die geringere Anzahl von Bytes von Vorteil sein. Wenn Sie sie über eine serielle Schnittstelle übertragen, kann die komprimierte Größe des Bitfelds ein Gewinner sein.
Also in Bezug auf Ihre Frage:
Gibt es eine gute Möglichkeit, dies zu testen?
Der einzige gute Weg, dies zu testen, besteht darin, Testfälle für beide Ansätze mit einem Muster zu schreiben, das genau zu Ihrer Anwendung passt. Es ist wirklich wichtig, welche Mischung von Operationen Sie ausführen, um zu entscheiden, ob der Unterschied vernachlässigbar oder signifikant ist.
Verwenden Sie bei dieser Art von Optimierungsexperimenten auf jeden Fall die Quellcodeverwaltung für Ihr Projekt. Sie können mit nur wenigen Klicks ein lokales GIT- oder Mercurial-Repository erstellen. Wenn Sie eine Kette von Kontrollpunkten beibehalten, können Sie Ihren Code zerreißen und die Auswirkungen verschiedener Implementierungen untersuchen. Wenn Sie falsch abbiegen, können Sie im Repository einfach zum letzten guten Punkt zurückkehren und einen anderen Pfad ausprobieren.
(Randnotiz: Dieses Mal besteht der Speicherkompromiss auch in die entgegengesetzte Richtung. Wenn Sie die Compileroptionen für Desktop-Klassenprozessoren durchsehen, finden Sie etwas, das als Strukturpacken bezeichnet wird . Mit dieser Option können Sie leere Bytes zwischen Einzelbytefeldern hinzufügen, so dass diese Bleiben Sie an Wort- oder Doppelwortgrenzen ausgerichtet. Dies mag verrückt erscheinen, um RAM absichtlich wegzuwerfen, aber auf Prozessoren mit 16 oder 32 Bit breiten Registern und Bussen können sogenannte wort- oder dword-ausgerichtete Speicheroperationen schneller sein als byteweise Operationen.)