看看在發佈模式下編譯的代碼的反彙編,差異是非常明顯的! 我刪除了內聯,並使用了兩個虛函數,以使編譯器不會優化太多,讓我們展示差異。
這是第一個功能。
013D1002 in al,dx
union {
float x;
int a;
} u;
u.x = x;
013D1003 fld dword ptr [x] // Loads a float on top of the FPU STACK.
013D1006 fstp dword ptr [x] // Pops a Float Number from the top of the FPU Stack into the destination address.
u.a &= 0x7FFFFFFF;
013D1009 and dword ptr [x],7FFFFFFFh // Execute a 32 bit binary and operation with the specified address.
return u.x;
013D1010 fld dword ptr [x] // Loads the result on top of the FPU stack.
}
這是第二個功能。
013D1020 push ebp // Standard function entry... i'm using a virtual function here to show the difference.
013D1021 mov ebp,esp
int b= *((int *)&a) & 0x7FFFFFFF;
013D1023 mov eax,dword ptr [a] // Load into eax our parameter.
013D1026 and eax,7FFFFFFFh // Execute 32 bit binary and between our register and our constant.
013D102B mov dword ptr [a],eax // Move the register value into our destination variable
return *((float *)(&b));
013D102E fld dword ptr [a] // Loads the result on top of the FPU stack.
在第一種情況下,浮點運算的數量和FPU堆棧的使用量更大。 這些函數正在執行你所要求的內容,所以並不奇怪。 所以我期望第二個函數更快。
現在...刪除虛擬和內聯的東西有點不同,很難在這裏編寫反彙編代碼,因爲編譯器當然做得很好,但我再說一遍,如果值不是常量,編譯器將在第一次使用更多浮點操作功能。 當然,整數運算比浮點運算更快。
你確定直接使用math.h abs函數比你的方法慢嗎? 如果內嵌正確,abs函數將會執行此操作!
00D71016 fabs
微優化像這樣的很難在長碼看,但如果你的函數被調用浮點運算的長鏈,晶圓廠將更好地工作,因爲值將是已經在FPU堆棧或SSE註冊! abs會更快,更好地被編譯器優化。
您無法測量在一段代碼中運行循環的優化的性能,您必須瞭解編譯器如何在實際代碼中混合在一起。
'std :: abs'相對於您的版本有多長? – avakar
btw ...爲什麼不使用std :: fabs?因爲這將使用適當的CPU指令集來計算絕對值(在intel架構上它是FABS),這比上面做的任何事情都要快得多。 –
Ahmed Masud:你確定嗎?我現在會測試它。 ...嗯,不完全明白爲什麼,但它出來簡單的晶圓廠功能是最快的:晶圓廠 - 0.922311,fastAbs(從上面) - 0.935108,吸收(也從上面) - 0.937011,絕對雙 - 0.936235。我很好奇這一點... – Vadim