Ich habe festgestellt, dass eine ARM-Verzweigungsanweisung 6 Zyklen zu dauern scheint, um auf einem ARM7TDMI-Prozessor ausgeführt zu werden. Es scheint, dass dies nicht passieren sollte, da in allen Referenzen, die ich gefunden habe, eine ARM7TDMI-Verzweigungsanweisung nur 3 Zyklen dauern sollte. Aber:
Die C-Funktion:
start_time = TC;
for (int i=0; i<120; i++) {
__asm("NOP");
}
end_time = TC;
Die Disassemblierung zeigt die Schleife als: (Update: Befehlsadressen hinzugefügt):
0x120 MOV R1, 0
0x124 B LOC0
start:
0x128 NOP
0x12C ADD R1, R1, 1
LOC0:
0x130 CMP R1, 120
0x134 BLT start
Das Ergebnis zeigt nun, dass die Schleife 1080 Zyklen benötigt (umgerechnet von einem in TC eingegebenen Timer-Zähler), dh 9 Zyklen pro Schleifenkern. Da NOP
, ADD
, CMP
alle Einzelzyklusbefehle sind, BLT
müssen 6 Zyklen sein.
Ich vermute einmal, ob meine Zeitmessungsmethode Fehler hat. NOP
Aber wenn ich im Schleifenkern 1 hinzufüge , würde die Zeiterhöhung genau 1 Zyklus betragen.
Was ist hier los?
(Update: Fix: Der ursprüngliche Disassemblierungscode war falsch geschrieben ADD R1, R1, 1
als ADD R1, R1
)
Vielen Dank für die hilfreichen Antworten und Kommentare, insbesondere @supercat, @Dzarda, @DaveTweed, @IgorSkochinsky, @WoutervanOoijen. Ich lasse Code vom Blitz laufen. Die CPU ist eine LPC23xx. Laut Benutzerhandbuch enthält es ein Memory Acceleration Module (MAM) für den gepufferten Flash-Zugriff. Und die vorgeschlagenen Flash-Fetch-Zyklen unter meiner CPU-Geschwindigkeit betragen genau 3 Zyklen.
Der start
im obigen Penalized-Loop-Kernel richtet sich an einer 8-Byte-Grenze aus. Wenn ich die Ausrichtung auf start
eine 16-Byte-Grenze ändere, verschwindet die Strafe von 3 zusätzlichen Zyklen. Dies kann durch die Flash-Prefetch-Puffergröße meiner CPU von 128 Bit (16 Byte) erklärt werden.
(@WoutervanOoijen) Beachten Sie, dass die 3-Zyklen-MAM-Flash-Abrufzeit nicht von der ARM-CPU ausgeführt wird, sondern vom MAM-Modul, das die Flash-Daten parallel zur CPU vorab abruft. In meinem Code mit start
Ausrichtung an der 8-Byte-Grenze CMP
befindet sich also die erste Anweisung im 128-Bit-MAM-Prefetch-Puffer (4-Anweisungen). Wenn die ARM-CPU ausführt BLT
, dauert es den ersten Zyklus, um die Anweisung zu "verstehen". Dann versucht er, einen Befehl abzurufen NOP
, der sich nicht im MAM-Vorabrufpuffer befindet. Das sollte der Moment sein, in dem die zusätzlichen 3 Zyklen passieren, wenn das MAM auf den Flash zugreift. Wenn sich die Anweisung im Puffer befindet (zusammen mit 3 anderen Anweisungen in der 32-Byte-Flash-Zeile), kann die ARM-CPU die Pipeline durch Abrufen (5. Zyklus) und Decodieren NOP
tatsächlich wieder auffüllenNOP
NOP
(6. Zyklus). Daraus ergeben sich die insgesamt 6 Zyklen.
Die Antwort auf meine Frage lautet also Ja, ein 6-Zyklus-Verzweigungsbefehl ist möglich, wenn ein Flash-Zugriffsstillstand vorliegt.
Wie @WoutervanOoijen betont, hat die obige Argumentation einen Fehler. Das Memory Acceleration Module des LPC23xx verfügt über einen zusätzlichen Branch-Trail-Buffer, der diese Art von wiederholten Re-Fetch-Loop-Verzweigungen vermeiden soll. Im LPC23XX-Benutzerhandbuch heißt es:
Der Verzweigungsspurpuffer erfasst die Zeile, an der eine solche nicht sequentielle Unterbrechung auftritt. Wenn dieselbe Verzweigung erneut genommen wird, wird die nächste Anweisung aus dem Verzweigungsspurpuffer genommen
Diese Aussage scheint nicht sehr klar darüber zu sein, was genau in den Branch Trail-Puffer geschrieben wird. Es könnte die letzte vorab abgerufene Flash-Zeile oder die letzte Flash-Zeile des Verzweigungsziels sein. In beiden Fällen hätte die Flash-Zugriffsstrafe nicht passieren dürfen, da die Flash-Zeile (0x120 ~ 0x12F) einschließlich der Verzweigungszielanweisung ( ) NOP
bereits im Branch Trail-Puffer sein sollte, wenn BLT
sie ausgeführt wird (zumindest ab dem zweiten Mal). .
(Übrigens, ich habe überprüft, dass das MAM in den vollständig aktivierten Modus versetzt wird, dh MAM_mode_control ist 2.)
Ich werde diese Frage aktualisieren, nachdem ich weitere Informationen dazu gefunden habe. Und ich würde es schätzen, wenn Sie irgendwelche Kommentare dazu haben, was hier passieren könnte, oder welche Tests durchgeführt werden können, um nach Hinweisen zu suchen.
Führen Sie Code aus dem RAM oder aus dem Flash aus? ARM-Prozessoren, die Code aus dem Flash ausführen, erfordern zumindest unter bestimmten Umständen häufig Wartezustände. Solche Prozessoren enthalten oft Hardware, die die meisten Wartezustände im gemeinsamen Code eliminieren kann, aber solche Hardware kann so einfach wie ein Einzelzeilenpuffer sein, der einen Zugriff auf dieselbe Flash-Zeile wie beim vorherigen Zugriff ermöglicht, um den Wartezustand zu vermeiden. Wenn das Verzweigungsziel das letzte Wort einer Flash-Zeile ist, würde der Flash zwei oder drei Zyklen benötigen, um dieses Wort abzurufen, und zwei oder drei Zyklen, um das folgende Wort abzurufen. Wenn einer der Zyklen gleichzeitig mit einer anderen CPU-Operation ausgeführt wird, würde dies eine Strafe von drei Zyklen hinterlassen.
start
an der 16-Byte-Grenze ausgerichtet sind. Zuvor ist es in der 8-Byte-Grenze.Werfen Sie einen Blick in das ARM-Infocenter, Abbildung 2 , und denken Sie daran, dass Sie mit der ARM7-Pipeline und nicht mit der dreistufigen M3-Pipeline arbeiten. Der Punkt bleibt gültig.
Zwischen Abruf und Ausführung können Zyklen liegen. Es ist sehr schwierig, Taktimpulse für Befehlszyklen auf einem modernen Pipeline-Kern zu zählen. Ich bin mir nicht sicher, ob es überhaupt deterministisch ist
Ich frage mich, ob die Pipeline an jeder Verzweigung neu beginnen muss. Sie könnten erwägen, eine Reihe dieser NOPs zu stapeln, anstatt zu verzweigen, um zu sehen, ob Ihr resultierendes Verhalten als Debugging-Schritt deterministischer ist.
In der Tat wurde ich aus diesem Grund davor gewarnt, NOPs für präzise Verzögerungen auf ARM-Plattformen zu verwenden.
NOP
@ScottSeidman Danke für den Vorschlag, anstelle von Schleifen
zu verwenden . Die Verwendung NOP
des Ergebnisses wäre richtig.
Dzarda
David Tweed
add
Zweitens kann es zu einem durch die Datenabhängigkeit zwischen den und den Befehlen verursachten Pipelinestillstand kommencmp
. Schließlich könnten 3 Zyklenblt
nur ein Mindestwert sein; zusätzliche Takte könnten erforderlich sein, wenn Teile der Dekodierpipeline geleert werden müssen, wenn die Verzweigung genommen wird.Scott Seidman
Igor Skochinsky
Wouter van Ooijen
Penghe Geng
Wouter van Ooijen
Penghe Geng
Wouter van Ooijen
Penghe Geng
Wouter van Ooijen
Penghe Geng