Ich habe mit IACA (Intels statische Code-Analysator) gespielt.
Es funktioniert gut, wenn es mit Montage-Schnipsel zu testen, wo ich manuell eingegeben der Magic Marker-Bytes kann, wie folgt aus:Verwenden von IACA mit Nicht-Assembly-Routine
procedure TSlice.BitSwap(a, b: integer);
asm
//RCX = self
//edx = a
//r8d = b
mov ebx, 111 // Start IACA marker bytes
db $64, $67, $90 // Start IACA marker bytes
xor eax, eax
xor r10d, r10d
mov r9d, [rcx] // read the value
mov ecx,edx // need a in cl for the shift
btr r9d, edx // read and clear the a bit
setc al // convert cf to bit
shl eax, cl // shift bit to ecx position
btr r9d, r8d // read and clear the b bit
mov ecx, r8d // need b in ecx for shift
setc r10b // convert cf to bit
shl r10d, cl // shift bit to edx position
or r9d, eax // copy in old edx bit
or r9d, r10d // copy in old ecx bit
mov [r8], r9d // store result
ret
mov ebx, 222 // End IACA marker bytes
db $64, $67, $90 // End IACA marker bytes
end;
Gibt es eine Möglichkeit/Suffix nicht Assembler-Code Präfix mit den erforderlichen Textmarkern, so dass ich den vom Compiler generierten Code analysieren?
Ich weiß, ich kann die erzeugte Baugruppe von der CPU-Ansicht copy-paste und eine Routine, dass schaffen, aber ich hatte gehofft, dass es einen einfacheren Workflow
EDIT
ist ich suche Lösungen, die im 64-Bit-Compiler funktionieren. Ich weiß, dass ich Assembler- und normalen Code im 32-Bit-Compiler mischen kann.
UPDATE
@ Dsm Vorschlag funktioniert. @ Rudys Trick nicht.
Der folgende Dummy-Code funktioniert:
Throughput Analysis Report
--------------------------
Block Throughput: 13.33 Cycles Throughput Bottleneck: Dependency chains (possibly between iterations)
Port Binding In Cycles Per Iteration:
---------------------------------------------------------------------------------------
| Port | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 |
---------------------------------------------------------------------------------------
| Cycles | 1.3 0.0 | 1.4 | 1.0 1.0 | 1.0 1.0 | 0.0 | 1.4 | 2.0 | 0.0 |
---------------------------------------------------------------------------------------
N - port number or number of cycles resource conflict caused delay, DV - Divider pipe (on port 0)
D - Data fetch pipe (on ports 2 and 3), CP - on a critical path
F - Macro Fusion with the previous instruction occurred
* - instruction micro-ops not bound to a port
^ - Micro Fusion happened
# - ESP Tracking sync uop was issued
@ - SSE instruction followed an AVX256/AVX512 instruction, dozens of cycles penalty is expected
X - instruction not supported, was not accounted in Analysis
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | |
---------------------------------------------------------------------------------
| 3^ | 0.3 | 0.3 | 1.0 1.0 | | | 0.3 | 1.0 | | CP | ret
| X | | | | | | | | | | int3
[... more int3's]
| X | | | | | | | | | | int3
| 1 | 1.0 | | | | | | | | | shl eax, 0x10
| 1 | | 0.6 | | | | 0.3 | | | | cmp eax, 0x64
| 3^ | | 0.3 | | 1.0 1.0 | | 0.6 | 1.0 | | CP | ret
| X | | | | | | | | | | int3
| X | | | | | | | | | | int3
[...]
Total Num Of Uops: 8
UPDATE 2
Wenn eine Call-Anweisung ist dort IACA zu bombardieren scheint und will nicht, um den Code zu analysieren. Sich über illegale Anweisungen beschweren. Die Grundidee funktioniert jedoch. Natürlich müssen Sie die ursprünglichen ret
und die damit verbundenen Kosten subtrahieren.
Beide Sequenzen sind genau 8 Bytes. Kannst du nicht: 'X: = $ 906764000000F6BB' am Anfang und' X: = $ 906764000000DEBB' am Ende deiner Routine, wo 'X' ein' UInt64' ist? –
Was ist eine statische Analyse, wenn Sie den Maschinencode nicht ändern können? –
@RudyVelthuis, als Basislinie zum Vergleich zu verwenden. Non-Assembly-Code kann inline, Assembly-Code nicht sein. – Johan