将值加倍时加法,乘法,左移运算

时间:2019-03-22 06:11:11

标签: c++

假设数字的值非常大,例如9,046,744,073,709,551,615。

我使用加法,乘法和左移将值翻倍。

#include <iostream>
using namespace std;

int main(){
   unsigned long long int value = 9046744073709551615;

   cout << (value + value) << endl;
   cout << (value * 2) << endl;  
   cout << (value << 1) << endl;

   return 0;
}

哪个计算会更快?

2 个答案:

答案 0 :(得分:1)

简短的答案是,没有其他选择更快。启用编译器优化后,它们会产生相同的代码。

对于在编译时知道该值的情况,程序集是这样的:Compiler Explorer link

movabs  rsi, -353255926290448386
call    std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long long>(unsigned long long)

它将常量加载到寄存器中并调用operator<<()。所有这三种选择都会产生这种优化的装配。

对于在运行时读取值的情况,程序集是这样的:Compiler Explorer link

mov     rax, QWORD PTR [rsp+8]
mov     edi, OFFSET FLAT:_ZSt4cout
lea     rsi, [rax+rax]
call    std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long long>(unsigned long long)

它使用加法(rax+rax)并调用operator<<()。同样,所有这三种选择都产生相同的装配。

答案 1 :(得分:0)

我刚刚从godbolt中选择了一个编译器。确实,完全没有区别。尝试编译器和优化级别。

-O0中使用x86-64_gcc的结果是以下结果的三倍:

    mov     rax, QWORD PTR [rbp-8]
    add     rax, rax
    mov     rsi, rax
    mov     edi, OFFSET FLAT:_ZSt4cout
    call    std::basic_ostream<char, std::char_traits<char> >::operator<<(unsigned long long)
    mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
    mov     rdi, rax
    call    std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))