2010-06-22 1 views

Antwort

18

Vor ARMv4 hatte ARM keine systemeigene Unterstützung für das Laden von Halbwörtern und signierten Bytes. Um ein vorzeichenbehaftetes Byte zu laden, mussten Sie LDRB dann Zeichen verlängern den Wert (es dann ASR es wieder runter). Dies ist schmerzhaft, so dass char standardmäßig unsigned ist.

In ARMv4 wurden Anweisungen hinzugefügt, um Halb- und vorzeichenbehaftete Werte zu verarbeiten. Diese neuen Anweisungen mussten in den verfügbaren Befehlsraum gequetscht werden. Begrenzungen des verfügbaren Platzes bedeuteten, dass sie nicht so flexibel wie die ursprünglichen Anweisungen gemacht werden konnten, die in der Lage sind, verschiedene Adressberechnungen durchzuführen, wenn sie den Wert laden.

So können Sie feststellen, dass LDRSB, zum Beispiel, ist nicht in der Lage, einen Abruf aus dem Speicher mit einer Adressberechnung zu kombinieren, während LDRB könnte. Dies kann Zyklen kosten. Manchmal können wir short -hohen Code bearbeiten, um auf Paare von ints zu arbeiten, um dies zu vermeiden.

Es gibt mehr Informationen hier auf meiner Website: http://www.davespace.co.uk/arm/efficient-c-for-arm/memaccess.html

+1

wow ich habe gehört, dass 'char' der signness Implementierung definiert ist, aber dies ist das erste Mal, dass ich eine echte Implementierung sehen, die verwendet standardmäßig ohne Vorzeichen –

2

Ich denke, es ist nur, dass die Anweisung für ARM-CPUs für unsigned optimiert ist. Einige Operationen können mit einer Anweisung für vorzeichenlose Typen durchgeführt werden, benötigen jedoch mehrere Anweisungen, wenn sie signiert sind. Deshalb denke ich, wenn ARM in den meisten (allen?) C- und C++ - Compilern kompiliert wird, ist es standardmäßig ein Zeichen ohne Vorzeichen und nicht das üblichere Zeichen.

2

Die einzigen Vorteile von unsignierten Typen, die ich mir vorstellen kann, sind, dass Divisions- und Modulo-Implementierungen etwas schneller sein können, und Sie können Tests wie if (unsigned_value < limit) statt if (signed_value >= 0 && signed_value < limit) durchführen.

Ich vermute, dass Ihr Handbuch möglicherweise veraltet ist. Jeder ARM, der heute benutzt wird, wird v4 oder später haben, und ich bin mir ziemlich sicher, dass keine Anweisungen schneller oder langsamer sind, je nach Signedness.

Auf älteren ARMs glaube ich, dass vorzeichenbehaftete Multiplikation langsamer sein könnte; Ich denke, dass eine vorzeitige Beendigung nur nach Nullen in den oberen Bits suchte, nicht nach allen Einsen, so dass Multiplikationen mit negativen Zahlen immer die maximale Zeit benötigen. Dies hängt jedoch vom Wert ab, nicht davon, ob der Typ signiert oder nicht signiert wurde. Ab mindestens ARMv4 funktioniert die vorzeitige Beendigung für negative Werte.

Auch glaube ich sehr frühen ARMs konnte nicht ein einzelnes Byte, nur ein Wort laden. So sollen Sie zwei Befehle benötigen ein Byte ohne Vorzeichen zu laden, und drei laden ein eine unterzeichneten:

ldr r0, [r1] 
and r0, r0, #0xff 

gegen

ldr r0, [r1] 
mov r0, r0, asl #24 
mov r0, r0, asr #24 ; but this could maybe be combined with later instructions 

im Vergleich (in diesen Tagen) ldrb r0, [r1] oder ldrsb r0, [r1] ein einziges Byte zu tun Belastung.

Auf einem modernen Prozessor ist es sehr unwahrscheinlich, dass unsignierte Typen einen messbaren Einfluss auf die Leistung haben. Verwenden Sie den Typ, der am sinnvollsten ist, und sehen Sie sich den Code dann genauer an, wenn Sie Leistungsengpässe erkannt haben.