回答
是。一個簡單的方法來展示這是編譯以下兩個功能,做同樣的事情,然後看看反彙編。
#include <stdint.h>
#include <math.h>
uint32_t foo1(uint32_t shftAmt) {
return pow(2, shftAmt);
}
uint32_t foo2(uint32_t shftAmt) {
return (1 << shftAmt);
}
cc -arch armv7 -O3 -S -o - shift.c
(我碰巧發現ARM彙編更容易閱讀,但如果你想86只是刪除拱形標誌)
_foo1:
@ BB#0:
push {r7, lr}
vmov s0, r0
mov r7, sp
vcvt.f64.u32 d16, s0
vmov r0, r1, d16
blx _exp2
vmov d16, r0, r1
vcvt.u32.f64 s0, d16
vmov r0, s0
pop {r7, pc}
_foo2:
@ BB#0:
movs r1, #1
lsl.w r0, r1, r0
bx lr
你可以看到foo2
只需要2個指令VS foo1
這需要幾條指令。它必須將數據移動到FP HW寄存器(vmov
),整數轉換爲浮動(vcvt.f64.u32
)調用exp
函數,然後將轉換的回答返回到一個UINT(vcvt.u32.f64
),並將其從FP HW移回GP寄存器。
+1。 – fuzz
大部分時間將在_exp2函數中進行,而不是在此處顯示的任何代碼中。 –
這取決於編譯器,但一般情況下(編譯器不完全是braindead時)是的,移位是一個CPU指令,另一個是函數調用,包括保存當前狀態以設置堆棧幀這需要很多指導。
通常是的,因爲移位對於處理器來說是非常基本的操作。
在另一方面,許多編譯器優化代碼,從而提高電源其實只是有點移位。
對於'雙'?我對此表示懷疑。 –
當然,但我們在這裏說'int's。 –
如果你打電話給'pow()',這是OP的例子。 –
是的。雖然我無法說多少。確定的最簡單方法是對其進行基準測試。
的pow
功能使用雙打......至少,如果它符合C標準。即使該函數在看到2
的基數時使用了位移,仍然會進行測試和分支以得出結論,屆時您的簡單位移將會完成。我們甚至沒有考慮到函數調用的開銷。
對於等價,我假設你想用1 << x
,而不是1 << 4
。
也許編譯器可以優化這兩個,但它不太可能將呼叫優化到pow
。如果你需要最快的方式來計算2的冪,那麼就通過移位來完成。
更新......既然我提到很容易基準,我決定來做到這一點。我碰巧擁有Windows和Visual C++,所以我使用了它。結果會有所不同。我的程序:
#include <Windows.h>
#include <cstdio>
#include <cmath>
#include <ctime>
LARGE_INTEGER liFreq, liStart, liStop;
inline void StartTimer()
{
QueryPerformanceCounter(&liStart);
}
inline double ReportTimer()
{
QueryPerformanceCounter(&liStop);
double milli = 1000.0 * double(liStop.QuadPart - liStart.QuadPart)/double(liFreq.QuadPart);
printf("%.3f ms\n", milli);
return milli;
}
int main()
{
QueryPerformanceFrequency(&liFreq);
const size_t nTests = 10000000;
int x = 4;
int sumPow = 0;
int sumShift = 0;
double powTime, shiftTime;
// Make an array of random exponents to use in tests.
const size_t nExp = 10000;
int e[nExp];
srand((unsigned int)time(NULL));
for(int i = 0; i < nExp; i++) e[i] = rand() % 31;
// Test power.
StartTimer();
for(size_t i = 0; i < nTests; i++)
{
int y = (int)pow(2, (double)e[i%nExp]);
sumPow += y;
}
powTime = ReportTimer();
// Test shifting.
StartTimer();
for(size_t i = 0; i < nTests; i++)
{
int y = 1 << e[i%nExp];
sumShift += y;
}
shiftTime = ReportTimer();
// The compiler shouldn't optimize out our loops if we need to display a result.
printf("Sum power: %d\n", sumPow);
printf("Sum shift: %d\n", sumShift);
printf("Time ratio of pow versus shift: %.2f\n", powTime/shiftTime);
system("pause");
return 0;
}
我的輸出:
379.466 ms
15.862 ms
Sum power: 157650768
Sum shift: 157650768
Time ratio of pow versus shift: 23.92
- 1. 使用指數** 0.5比math.sqrt效率低?
- 2. 基於位選擇的算法效率
- 3. R:統計/計算效率
- 4. 效率低下的擴展算法
- 5. 64位整數在JVM中的效率低於32位整數嗎?
- 6. Swift - 計算閉包內的不可變性效率低下嗎?
- 7. 從PHP中最高有效位和最低有效位計算小數
- 8. 高效算法用於在間隔計數數的頻率
- 9. 計算速率參數:指數分佈
- 10. 計算頻率的有效算法?
- 11. Tsql日期計算效率
- 12. PHP質量計算效率
- 13. 關於高效頻率計算的數據結構決策
- 14. jQuery效率低下?
- 15. 計算R中的平均指數與指數的比率
- 16. 計算T(n)?算法效率(Python)
- 17. 與矩形相比,繪製圓的效率真的很低嗎?
- 18. 最近的質心分類器真的效率低下嗎?
- 19. 用於基於Java的8位計算機仿真器的VT100終端仿真
- 20. R函數用於計算某個值的頻率低於特定值的頻率
- 21. Hazelcast建立在CountAggregation真的效率低下?
- 22. 算法效率vs效率
- 23. JSXGraph。計算點的位移
- 24. 計算真假的有效方法
- 25. 是治療2個uint8_ts爲低效率
- 26. 這是mysql語句效率低下嗎?
- 27. 這是XSLT效率低下嗎?
- 28. 這是否像效率低下?
- 29. 效率的紅移表設計
- 30. 計算正則表達式的效率
你試過了嗎? –
「那麼多」是多少?你必須期望它效率較低,否則你不會問這個問題。所以我們在這裏有一個輕率的問題,沒有嘗試研究,期望讀心術。-1 –
這並不是我期待的,有人評論了pow(2,x);我在自己的代碼中說過「總是做一些移位而不是2的權力」,而我以前從來沒有聽說過,所以我在這裏問了這個問題。 – patrick