【问题标题】:Would it be faster / using less memory to return in each case of if else?在 if else 的每种情况下返回会更快/使用更少的内存吗?
【发布时间】:2018-04-18 09:41:23
【问题描述】:

最近,我在我的 CS 研究中获得了一个代码示例(参见代码 #1),我尝试了解我的第二版代码是否会更快或使用更少的内存。 你对我的问题有答案吗?

// Code #1
double f(double b, double x)
{
    double s;
    if (x == 0.0)
        s = 1.0;
    else
        s = sin(x)/x;
    return s + b;
}

// Code #2
double f(double b, double x)
{
    // I thought this would be faster and using less memory due to 
    // not declaring a new double
    if (x == 0.0)
        return 1.0 + b;
    else
        return sin(x)/x + b;
}

谢谢你们的帮助。

【问题讨论】:

  • c++不是c,请只选择一个标签,这样才能得到你需要的答案
  • 除非您使用的编译器是 ****,否则它们可能会被优化为相同的代码。您可以随时拆卸并亲自查看。从理论上讲,第二个可能会更快,只是在实践中可能不会。
  • 没有区别。编译器可以轻松进行这样的转换。无论如何sin(x) 将花费最多的时间。
  • @George - 几乎 相同的代码 (demo)
  • @HB - 这与代码审查无关。不要虚假地建议它。

标签: c performance memory


【解决方案1】:

我已经生成了这两种情况的程序集。

案例一:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 48
        movsd   QWORD PTR [rbp-24], xmm0
        movsd   QWORD PTR [rbp-32], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-32]
        jne     .L2
        movsd   xmm0, QWORD PTR .LC1[rip]
        movsd   QWORD PTR [rbp-8], xmm0
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-32]
        mov     QWORD PTR [rbp-40], rax
        movsd   xmm0, QWORD PTR [rbp-40]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-32]
        movsd   QWORD PTR [rbp-8], xmm0
.L4:
        movsd   xmm0, QWORD PTR [rbp-8]
        addsd   xmm0, QWORD PTR [rbp-24]
        leave
        ret
.LC1:
        .long   0
        .long   1072693248

案例 2:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        movsd   QWORD PTR [rbp-8], xmm0
        movsd   QWORD PTR [rbp-16], xmm1
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jp      .L2
        pxor    xmm0, xmm0
        ucomisd xmm0, QWORD PTR [rbp-16]
        jne     .L2
        movsd   xmm1, QWORD PTR [rbp-8]
        movsd   xmm0, QWORD PTR .LC1[rip]
        addsd   xmm0, xmm1
        jmp     .L4
.L2:
        mov     rax, QWORD PTR [rbp-16]
        mov     QWORD PTR [rbp-24], rax
        movsd   xmm0, QWORD PTR [rbp-24]
        call    sin
        divsd   xmm0, QWORD PTR [rbp-16]
        addsd   xmm0, QWORD PTR [rbp-8]
.L4:
        leave
        ret
.LC1:
        .long   0
        .long   1072693248

没有区别。所以,它们之间没有速度优化。所以,代码优化依赖于编译器。

【讨论】:

  • .LC1[rip] 是什么?它会做什么?
【解决方案2】:

简短回答:别担心!

长答案:

sin 将在此函数中花费最多时间,因此如果有的话,一些额外的指令不会有任何明显的效果。

尽管有疑问,look 在生成的代码处。

在 x86_64 上使用 GCC 6.3,第一个版本多使用 1 个寄存器 (xmm2),但优化器能够更好地重新排序指令。

版本 1:

        ucomisd xmm1, QWORD PTR .LC1[rip]
        movapd  xmm2, xmm0
        jp      .L5
        movsd   xmm0, QWORD PTR .LC0[rip]
        je      .L7
.L5:
        movapd  xmm0, xmm1
        sub     rsp, 24
        movsd   QWORD PTR [rsp+8], xmm2
        movsd   QWORD PTR [rsp], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp]
        movsd   xmm2, QWORD PTR [rsp+8]
        add     rsp, 24
        divsd   xmm0, xmm1
        addsd   xmm0, xmm2
        ret
.L7:
        addsd   xmm0, xmm2
        ret

版本 2:

        ucomisd xmm1, QWORD PTR .LC0[rip]
        jp      .L2
        je      .L10
.L2:
        sub     rsp, 24
        movsd   QWORD PTR [rsp], xmm0
        movapd  xmm0, xmm1
        movsd   QWORD PTR [rsp+8], xmm1
        call    sin
        movsd   xmm1, QWORD PTR [rsp+8]
        divsd   xmm0, xmm1
        addsd   xmm0, QWORD PTR [rsp]
        add     rsp, 24
        ret
.L10:
        addsd   xmm0, QWORD PTR .LC1[rip]
        ret

那么这两个版本的性能差异有多大呢?只有性能测试才能确定(但我猜你不会看到任何差异)。

【讨论】:

    【解决方案3】:

    只声明变量不只是占用内存。

    int a = 1 + 2;
    int b = 3;
    int c = a + b;
    

    此代码将采用与以下代码相同的值

    int c = 1 + 2 + 3;
    

    因为最终处理器将在单核中一次执行一项操作。
    第二个代码添加两个数字并将其保存在堆栈中,然后将第三个数字添加到前两个数字的结果中。

    【讨论】:

      【解决方案4】:

      这取决于编译器和优化标志。一般来说,两个代码都会给出相同的结果。

      【讨论】:

        猜你喜欢
        • 2018-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多