原始代碼產生在使用gcc -O3
進行編譯時遵循64位彙編:
movl %edi, %eax
leal -18(%rax), %ecx
movl %ecx, %edx
sarl $31, %edx
shrl $29, %edx
addl %edx, %ecx
andl $7, %ecx
subl %edx, %ecx
je .L2
addl $8, %eax
subl %ecx, %eax
.L2:
rep
正如在評論你的問題建議,改變參數unsigned int
允許在以下裝配更大的優化和結果:
leal -18(%rdi), %edx
movl %edi, %eax
andl $7, %edx
je .L3
leal 8(%rdi), %eax
subl %edx, %eax
.L3:
rep
四捨五入到8
倍數可以通過增加執行7
並用~7
掩蓋。它的工作原理是這樣的:如果最後三位不全爲零,則將7
加入第4位,否則不進位。所以,你的功能可以簡化爲:
return (((length - 18) + 7) & ~7) + 18;
或簡單:
return ((length - 11) & ~7) + 18;
GCC編譯的最後一行簡單:
leal -11(%rdi), %eax
andl $-8, %eax
addl $18, %eax
注意,lea
(加載有效地址)instruciton經常被「濫用」,因爲它能夠計算簡單的線性組合,如reg1 + size*reg2 + offset
除非你的編譯器死腦筋,否則幾乎肯定會比單純的凡人優化得更好:-) – paxdiablo 2012-07-27 08:49:35
爲什麼你認爲你甚至需要「優化」這個特定的函數?你有沒有對其進行分析並確定性能問題? – 2012-07-27 08:55:27
「優化」是什麼意思?如果你的意思是提高運行時間,我懷疑你正在試圖解決錯誤的問題,並且你會比編譯器開關更好地運行,而不是試圖微調函數。也就是說,如果你真的想優化這個功能,我懷疑你最好的選擇是潛入彙編代碼並在那裏優化;你可能會修剪掉一兩個多餘的操作。您可能還會發現重構對生成的彙編代碼沒有任何影響。 – 2012-07-27 09:05:01