簡體   English   中英

C++ 優化器:除法

[英]C++ Optimizer : division

假設我有 2 個if語句:

if (frequency1_mhz > frequency2_hz * 1000) {// some code}

if (frequency1_mhz / 1000 > frequency2_hz ) {// some code}

我想兩者的功能完全相同,但我猜第一個帶有乘法的語句比除法更有效。

C++ 編譯器會對此進行優化嗎? 或者這是我在設計代碼時應該考慮的事情

是和否。

  1. 代碼不一樣:
  • 由於四舍五入,結果可能存在差異(例如frequency1_mhz=1001frequency2_hz=1
  • 第一個版本可能比第二個版本更快溢出。 例如,1000000000 的frequency2_hz會溢出一個int (並導致UB)
  1. 仍然可以使用乘法進行除法。

如果不確定,只需查看生成的程序集。

這是為兩個版本生成的程序集。 第二個更長,但仍然沒有分割。

version1(int, int):
        imul    esi, esi, 1000
        xor     eax, eax
        cmp     esi, edi
        setl    al
        ret
version2(int, int):
        movsx   rax, edi
        imul    rax, rax, 274877907     ; look ma, no idiv!
        sar     edi, 31
        sar     rax, 38
        sub     eax, edi
        cmp     eax, esi
        setg    al
        movzx   eax, al
        ret

不,這些不是等價的statemets,因為除法不是浮點數或整數乘法的精確倒數。

  • 整數除法向下舍入正分數
int f1=999;
int f2=0;

static_assert(f1>f2*1000);

static_assert(f1/1000==f2);
  • 倒數並不精確:
static_assert(10.0!=10*(1.0/10));

如果它們是用-O3構建的浮點數,GCC 將生成相同的程序集(無論好壞)。

bool first(float frequency1_mhz,float frequency2_hz) {
    return frequency1_mhz > frequency2_hz * 1000;
}

bool second(float frequency1_mhz,float frequency2_hz) {
    return frequency1_mhz / 1000 > frequency2_hz;
}

大會

first(float, float):
        mulss   xmm1, DWORD PTR .LC0[rip]
        comiss  xmm0, xmm1
        seta    al
        ret
second(float, float):
        divss   xmm0, DWORD PTR .LC0[rip]
        comiss  xmm0, xmm1
        seta    al
        ret
.LC0:
        .long   1148846080

所以,真的,它以相同的代碼結束:-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM