che*_*kow 13 c++ alias runtime reference
也许这是编译器特定的东西.如果是这样,gcc(g ++)怎么样?如果您使用这样的变量引用/别名:
int x = 5;
int& y = x;
y += 10;
Run Code Online (Sandbox Code Playgroud)
它实际上需要比我们不使用引用更多的周期.
int x = 5;
x += 10;
Run Code Online (Sandbox Code Playgroud)
换句话说,机器代码是否发生变化,或者"别名"是否仅在编译器级别发生?
这似乎是一个愚蠢的问题,但我很好奇.特别是在可能暂时重命名某些成员变量以便数学代码更易于阅读的情况下.当然,我们并没有在这里谈论瓶颈......但这是我正在做的事情,所以我只是想知道是否存在任何"实际"差异......或者它是否只是化妆品.
Kor*_*icz 11
它可以被视为别名,但不是效率方面.在引擎盖下,引用是一个具有更好语法和更高安全保证的指针.因此,您有一个"取消引用"操作运行时惩罚.除非编译器优化它,但我通常不会指望它.
如果编译器是否会对其进行优化,那么除了查看生成的程序集之外别无他法.
的确,在大多数情况下,引用实现了“别名”的概念,别名是它们绑定到的对象的替代名称。
但是,通常情况下,引用是通过指针实现的。但是,一个好的编译器仅在运行时确定实际绑定的情况下才使用实际指针来实现引用。如果绑定在编译时是已知的(并且类型匹配),则编译器通常会将引用实现为同一对象的替代名称,在这种情况下,通过引用访问该对象(与访问相比不会产生性能损失)它的原始名称)。
您的示例就是您不希望参考获得任何性能损失的示例之一。
我比较了 Gnu/Linux 上的 2 个程序。下面仅显示了 GCC 输出,但 clang 结果得出了相同的结论。
海湾合作委员会版本: 4.9.2
铿锵版本: 3.4.2
1.cpp
#include <stdio.h>
int main()
{
int x = 3;
printf("%d\n", x);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
2.cpp
#include <stdio.h>
int main()
{
int x = 3;
int & y = x;
printf("%d\n", y);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试 1:不进行优化
gcc -S --std=c++11 1.cpp
gcc -S --std=c++11 2.cpp
1.cpp 生成的程序集较短。
尝试2:优化
gcc -S -O2 --std=c++11 1.cpp
gcc -S -O2 --std=c++11 2.cpp
最终的组装结果是完全相同的。
1.cpp,没有优化
.file "1.cpp"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $3, -4(%rbp)
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.9.2-10) 4.9.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
2.cpp,没有优化
.file "2.cpp"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl $3, -12(%rbp)
leaq -12(%rbp), %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.9.2-10) 4.9.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
1.cpp,有优化
.file "1.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.section .text.unlikely,"ax",@progbits
.LCOLDB1:
.section .text.startup,"ax",@progbits
.LHOTB1:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB12:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $3, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE12:
.size main, .-main
.section .text.unlikely
.LCOLDE1:
.section .text.startup
.LHOTE1:
.ident "GCC: (Debian 4.9.2-10) 4.9.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
2.cpp,有优化
.file "1.cpp"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "%d\n"
.section .text.unlikely,"ax",@progbits
.LCOLDB1:
.section .text.startup,"ax",@progbits
.LHOTB1:
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB12:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $3, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE12:
.size main, .-main
.section .text.unlikely
.LCOLDE1:
.section .text.startup
.LHOTE1:
.ident "GCC: (Debian 4.9.2-10) 4.9.2"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
优化 GCC 输出时不存在运行时成本。clang 也是如此(使用版本 3.4.2 进行测试):当优化打开时,两个程序中生成的汇编代码是相同的。
归档时间: |
|
查看次数: |
2482 次 |
最近记录: |