[英]Do 32-bit and 64-bit registers cause differences in CPU micro architecture?
我試圖比較 Peter Cordes 在回答“將 CPU 寄存器中的所有位設置為 1”的問題時提到的方法。
因此,我編寫了一個基准測試,將所有 13 個寄存器設置為除e/rsp
rsp、 e/rbp
和e/rcx
之外的所有位 1。
代碼如下所示。 使用times 32 nop
來避免 DSB 和 LSD 的影響。
mov ecx, 100000000
Align 32
.test3:
times 32 nop
mov rax,-1
mov rbx,-1
;mov ecx,-1
mov rdx,-1
mov rdi,-1
mov rsi,-1
mov r8,-1
mov r9,-1
mov r10,-1
mov r11,-1
mov r12,-1
mov r13,-1
mov r14,-1
mov r15,-1
dec ecx
jge .test3
jmp .out
我測試了他提到的以下方法,完整的代碼在這里
mov e/rax, -1
xor eax, eax
dec e/rax
xor ecx, ecx
lea e/rax, [rcx-1]
or e/rax, -1
為了使這個問題更簡潔,我將使用group1 a (g1a)
來替換下表中的mov eax,-1
。
數字 | 圖案 | 測試編號 |
---|---|---|
組1a | 移動 eax,-1 | 測試 7 |
組 1 b | mov rax,-1 | 測試3 |
組2a | xor eax, eax / dec eax | 測試6 |
組 2 b | xor eax, eax / dec rax | 測試2 |
組3a | xor ecx, ecx / lea eax, [rcx-1] | 測試0 |
組 3 b | xor ecx, ecx / lea rax, [rcx-1] | 測試1(測試00) |
組4a | 或 eax,-1 | 測試5 |
組 4 b | 或 rax,-1 | 測試1 |
下表顯示從第 1 組到第 3 組,當使用 64 位寄存器時,每個循環多出 1 個周期。
IDQ_UOPS_NOT_DELIVERED 也會增加,這可以解釋循環次數的增加。 但這可以解釋每個循環確切的多 1 個循環嗎?
循環 | MITE 循環 (r1002479) | MITE 4 微秒周期 (r4002479) | IDQ UOPS 未交付(r19c) | |
---|---|---|---|---|
g1a | 1,300,903,705 | 1,300,104,496 | 800,055,137 | 601,487,115 |
g1b | 1,400,852,931 | 1,400,092,325 | 800,049,313 | 1,001,524,712 |
g2a | 1,600,920,156 | 1,600,113,480 | 1,300,061,359 | 501,522,554 |
g2b | 1,700,834,769 | 1,700,108,688 | 1,300,057,576 | 901,467,008 |
g3a | 1,701,971,425 | 1,700,093,298 | 1,300,111,482 | 902,327,493 |
g3b | 1,800,891,861 | 1,800,110,096 | 1,300,059,338 | 1,301,497,001 |
g4a | 1,201,164,208 | 1,200,122,275 | 1,100,049,081 | 201,592,292 |
g4b | 1,200,553,577 | 1,200,074,422 | 1,100,031,729 | 200,772,985 |
此外,g2a 和 g2b 的端口分布是不同的,不像 g1a 和 g1b(g1a 與 g1b 的端口分布相同),或者 g3a 和 g3b。
如果我評論times 32 nop
,這種現象就會消失。 跟MITE有關系嗎?
p0 | p1 | p2 | p3 | p4 | p5 | p6 | p7 | |
---|---|---|---|---|---|---|---|---|
g1a | 299,868,019 | 300,014,657 | 5,925 | 7,794 | 16,589 | 300,279,232 | 499,885,294 | 7,242 |
g1b | 299,935,968 | 300,085,089 | 6,622 | 8,758 | 18,842 | 299,935,445 | 500,426,436 | 7,336 |
g2a | 299,800,192 | 299,758,460 | 7,461 | 9,635 | 20,622 | 399,836,486 | 400,312,354 | 8,446 |
g2b | 200,047,079 | 200,203,026 | 7,899 | 9,967 | 21,539 | 500,542,313 | 500,296,034 | 9,635 |
g3a | 36,568 | 550,860,773 | 7,784 | 10,147 | 22,538 | 749,063,082 | 99,856,623 | 9,767 |
g3b | 36,858 | 599,960,197 | 8,232 | 10,763 | 23,086 | 700,499,893 | 100,078,368 | 9,513 |
g4a | 200,142,036 | 300,600,535 | 5,383 | 6,705 | 15,344 | 400,045,302 | 500,364,377 | 6,802 |
g4b | 200,224,703 | 300,284,609 | 5,464 | 7,031 | 15,817 | 400,047,050 | 499,467,546 | 6,746 |
環境:英特爾 i7-10700、ubuntu 20.04 和 NASM 2.14.02。
用英語解釋這個對我來說有點困難。 如果描述不清楚,請發表評論。
您所有示例中的瓶頸是預解碼器。
我用我的模擬器 uiCA ( https://uica.uops.info/ , https://github.com/andreas-abel/uiCA ) 分析了你的例子。 它預測以下吞吐量,與您的測量結果非常匹配:
TP | 關聯 | |
---|---|---|
g1a | 13.00 | https://uica.uops.info/?code=... |
g1b | 14.00 | https://uica.uops.info/?code=... |
g2a | 16.00 | https://uica.uops.info/?code=... |
g2b | 17.00 | https://uica.uops.info/?code=... |
g3a | 17.00 | https://uica.uops.info/?code=... |
g3b | 18.00 | https://uica.uops.info/?code=... |
g4a | 12.00 | https://uica.uops.info/?code=... |
g4b | 12.00 | https://uica.uops.info/?code=... |
uiCA 生成的跟蹤表提供了有關代碼執行方式的一些見解。 例如,對於 g1a,它會生成以下跟蹤:
您可以看到,對於 32 個 nop,預解碼器需要 8 個周期,而對於剩余的指令,它需要 5 個周期,它們加起來對應於您測量的 13 個周期。
您可能會注意到,在某些周期中,只有少量指令被預解碼; 例如,在第四個周期,只有一條指令被預解碼。 這是因為預解碼器在對齊的 16 字節塊上工作,它每個周期最多可以處理 5 條指令(請注意,一些消息來源錯誤地聲稱它每個周期可以處理 6 條指令)。
您可以在本文中找到有關預解碼器的更多詳細信息,例如它如何處理跨越 16 字節邊界的指令。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.