2014-01-29 81 views
3

是否以相同的速度做右移測試位與左移相同的速度?

#define CHECK_BIT_BOOL(var,pos) ((var>>(pos)) & 1) 

#define CHECK_BIT(var,pos) ((var) & (1<<(pos))) 

的目標是不使用BOOL宏象:

#define BOOL(x) (!(!(x))) 

BOOL(CHECK_BIT(foo, 3)); 

它是更好的事: CHECK_BIT_BOOL(foo,3);

general test bit question

+2

我檢查了ICC,Clang和GCC,並且在我測試過的所有情況下(這不是所有的情況),它使得*在字面上沒有區別*,因爲發射的代碼完全相同。即使「pos」是一個常數。 – harold

+0

好的,我的用例是gcc 4.7,用cpu = cortex-A8 -O3 –

+1

C有時候非常接近硬件。在這種情況下,你的問題實質上歸結爲:「邏輯左移指令是否需要在已知世界中的每個CPU上佔用與邏輯右移相同數量的CPU週期,以及布爾AND指令?」這樣的問題太廣泛了,沒有任何意義。一般來說,沒有考慮到特定的系統,說優化是沒有意義的。 – Lundin

回答

4

當前的C編譯器在將典型代碼轉換爲最佳機器語言時非常智能。大部分時間試圖智能化編譯器會將其混淆成生成啞代碼。

現代CPU能夠一次執行多個操作,無論何時使用它可能會被其他操作遮蔽,並且沒有任何區別。而且CPU的速度比內存更快,大多數程序的內存訪問速度比計算速度慢得多。

除非代碼在數百萬臺計算機上每天運行數千次,否則您的時間編程比通過此類微優化獲得的運行時獲得的任何增益都更有價值。專注於簡單,乾淨,明顯的正確和可理解的代碼。下週閱讀時,您會很感激。

-1

如果var和pos不在內存中,但已經在寄存器中,CHECK_BIT_BOOL和CHECK_BIT非常快。即使它在內存中 - 你不能更快得到它(如果var是1個字節,你可以創建256 * 8結果數組,並立即返回結果[var + 256 * 8]立即返回結果,但它會比在做>>和&)。

0

如果pos是一個常量,那麼CHECK_BIT可能稍微快一點,因爲在運行時不需要進行轉換。否則,兩者都可能是相同的。但正如你所指出的那樣,如果你需要將結果限制爲零或一,你需要在CHECK_BIT之後做更多的工作。

這當然取決於您的目標平臺,並且如果您的性能要求足夠嚴格以保證擔心單個處理器指令的成本,則必須在實際系統上剖析和測量真實性能。