使用uiCA,我為以下代碼生成了一個跟蹤表。
cvtsi2ss xmm0, eax
addss xmm0, xmm0
https://uica.uops.info/tmp/780bce9e56ee4a718d5369deb1326215_trace.html
您可以看到每個都必須等待上一次迭代完成,cvtsi2ss因為它取決于32:127.xmm0
但是,更改cvtsi2ss為rsqrtss會產生很大的不同。
rsqrtss xmm0, xmm1
addss xmm0, xmm0
https://uica.uops.info/tmp/8897a7d45c8348e68279aea4d0b18e15_trace.html
每個都rsqrtss與前一個迭代并行執行。我不明白,因為rsqrtss產生一個位32:127不變的輸出,就像cvtsi2ss,所以我認為它應該等待輸出暫存器上的任何操作完成,就像cvtsi2ss做的那樣。
看完答案后,我跑了一個簡單的測驗,似乎可以肯定 uiCA 有一個錯誤。
IACA也無法捕獲輸出依賴關系。
如果測驗代碼錯誤,請糾正我。
__asm__ (
R"(.section .text
.balign 16
noXor:
mov eax, 0x3f800000
movd xmm1, eax
rdtscp
shl rdx, 32
or rax, rdx
mov rdi, rax
mov ecx, 1 << 30
jmp noXor_loop
.balign 16
noXor_loop:
rsqrtss xmm0, xmm1
addss xmm0, xmm0
dec ecx
jnz noXor_loop
rdtscp
shl rdx, 32
or rax, rdx
sub rax, rdi
ret
.balign 16
yesXor:
mov eax, 0x3f800000
movd xmm1, eax
rdtscp
shl rdx, 32
or rax, rdx
mov rdi, rax
mov ecx, 1 << 30
jmp yesXor_loop
.balign 16
yesXor_loop:
xorps xmm0, xmm0
rsqrtss xmm0, xmm1
addss xmm0, xmm0
dec ecx
jnz yesXor_loop
rdtscp
shl rdx, 32
or rax, rdx
sub rax, rdi
ret)"
);
unsigned long long noXor(void);
unsigned long long yesXor(void);
#include <stdio.h>
int main() {
for (int i = 0; i < 4; i) {
printf("noXor: %llu yesXor: %llu\n", noXor(), yesXor());
}
return 0;
}
noXor: 4978836501 yesXor: 696810039
noXor: 4971780086 yesXor: 690780109
noXor: 4977293771 yesXor: 687404710
noXor: 5499602729 yesXor: 687954399
uj5u.com熱心網友回復:
在真實硬體上進行測驗,您將看到預期的結果:作為 xmm0 -> xmm0 依賴鏈的一部分,rsqrtss xmm0, xmm1有4 個周期延遲。(在我的 Skylake 上)。
這是UICA中的一個錯誤。或者實際上在它使用的https://uops.info/資料中 - 您的跟蹤包含指向rsqrtssuops.info 頁面的鏈接,我們可以在其中看到他們只測量了operand 2 → 1案例的延遲,沒有1 → 1. 撰寫該測驗時,作者可能復制/粘貼了rsqrtps測驗并忘記為輸出依賴項添加測驗。
如果沒有在真正的 CPU 上測驗自己,只有在實際測驗中測量1 → 1了rsqrtss. 如果沒有這樣的測驗,正確的假設是缺少測驗(因此 UICA 結果是錯誤的),而不是延遲實際上為零。
許多指令對任何 CPU 都沒有輸出依賴性,因此https://uops.info/并沒有對它們進行全部測驗是有道理的。我們寧愿將rsqrtps延遲列為4than [0:4],除非有一些 CPU 不為零。
當沒有測驗資料時,UICA 將假定沒有輸出依賴是有道理的;這對于沒有輸出依賴的指令是正常的。
但當然rsqrtss 應該分別測驗從每個運算元到目的地的延遲。它不為零,但至少理論上 CPU 允許合并目標的延遲轉發是可能的,因此實際測驗而不是假設它與正確的源相同是明智的。(我不知道單個 uop 允許延遲轉發的任何 x86 CPU,因此來自不同輸入的不同延遲通常只發生在多 uop 指令中。不像某些 ARM CPU,它們的 FMA 和/或整數 MAC 單元允許延遲轉發加數。)
順便說一句,您的推理是正確的,rsqrtss除非硬體對 XMM regs 進行部分注冊重命名,否則確實具有依賴性。但是沒有真正的硬體可以做到這一點。
PIII 和 Pentium-M 必須分別撰寫 XMM 的每個 64 位一半,也許可以不撰寫另一半,但rsqrtss由于英特爾的短視設計選擇,剩下的一半未修改。(現在我很好奇 Pentium-M 是否cvtsi2sd xmm0, eax具有sqrtsd xmm0, xmm1錯誤的輸出依賴性。)但是當前的 CPU 一次寫入整個 XMM 暫存器。
AVX 版本vrsqrtss甚至需要一個額外的源運算元來合并,它可以與結果寫入的目標分開。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/486330.html
上一篇:模塊化編程aarch64匯編
