15 c c++ assembly gcc constants
我在几个函数中定义了很多常量数组.类似于以下内容:
const float values[4] = {-4312.435f, -432.44333f, 4.798, 7898.89};
Run Code Online (Sandbox Code Playgroud)
在检查gcc汇编器输出后,我注意到这些常量是在每次运行函数时生成的.那是非常低效的.我怀疑这是因为C/C++规范说即使数据是const,编译器也不能假设它不会被修改(例如通过const_cast).是否有可能强制gcc不这么认为?
我想将这些常量定义在函数体内,因为它们非常复杂.将常量保持在他们使用的位置附近有助于可维护性.
编辑
不幸的是,即使定义了常量static,它们也会在每次运行时重新生成.如果有帮助我使用-O3.
EDIT2
好的,抱歉第一次编辑,我需要进一步调查.似乎特定的设置以前以某种方式不允许gcc初始化常量而不重新生成它们.
EDIT3
问题出在我的测试用例中,我在附近定义了两个数组,但其中一个数组是为了生成的.然后汇编程序误导了我.再次抱歉,谢谢!
rli*_*bby 12
用static关键字声明它们.
编辑:回复您的评论,以便我可以向您展示一些代码:
这是预期的行为.你在做什么或看到不同的东西?
$ cat foo.c++
int main(void)
{
static const float foos[] = {1.234f, 5.678f, 9.012f};
return 0;
}
$ g++ -S foo.c++
$ cat foo.s
.file "foo.c++"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.section .rodata
.align 4
.type _ZZ4mainE4foos, @object
.size _ZZ4mainE4foos, 12
_ZZ4mainE4foos:
.long 1067316150
.long 1085649453
.long 1091580199
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)
asc*_*ler 11
编译器实际上可以假设定义为const永远不会改变的值.(通过const变量访问的东西是另一个故事;我只讨论定义可见且具有的情况const.)这里得到的问题是标准说如果你递归地调用你的函数,那么地址values将是每次都不一样.
因此,使用语言功能意味着每次调用函数时声明都引用相同的内容.也就是说,一个static函数变量:
static const float values[4] = {-4312.435f, -432.44333f, 4.798, 7898.89};
Run Code Online (Sandbox Code Playgroud)
将定义更改为
static const float values[4] = {-4312.435f, -432.44333f, 4.798, 7898.89};
Run Code Online (Sandbox Code Playgroud)
静态数组不会放在函数堆栈中,因此不会为每个函数调用重新生成它们.
您还可以尝试将此数组从函数移到外部(使其成为具有某些前缀的全局数组function1_values).
编辑:
如果你将这些"flds"或者的计数统计"movss"为再生 - 那就不是.常量将存储在.rodataelf文件的部分中,但要使用它们,编译器必须将它们加载到寄存器中.所以fld&movss只会从内存中加载常量,如果不加载它就不可能从内存中获取值.
示例代码:
int function4(float *a, int sz)
{
int i;
const float values[4] = {-4312.435f, -432.44333f, 4.798, 7898.89};
for(i=4;i<sz;i++);
a[i]+=a[i-1]*values[0]+a[i-2]*values[1]+a[i-3]*values[2]+a[i-4]*values[3];
return i;
}
Run Code Online (Sandbox Code Playgroud)
gcc-4.5.2 -O3 ac -fverbose-asm -mfpmath = sse -march = native -S
Assembelr for loop body:
.L2:
movl -20(%ebp), %ecx # %sfp, D.2677
leal (%edx,%ecx), %ecx #, D.2677
movss .LC0, %xmm0 #, tmp192 << THIS is a constant loading
mulss (%edx,%edi), %xmm0 #* prephitmp.46, tmp192
movss .LC1, %xmm1 #, tmp179
mulss (%edx,%esi), %xmm1 #* prephitmp.46, tmp179
addss %xmm1, %xmm0 # tmp179, tmp192
movss .LC2, %xmm1 #, tmp183
mulss (%edx,%ebx), %xmm1 #* prephitmp.46, tmp183
addss %xmm1, %xmm0 # tmp183, tmp192
movss .LC3, %xmm1 #, tmp187
movl -16(%ebp), %ebx # %sfp,
Run Code Online (Sandbox Code Playgroud)
常量存储在.rodata:
.section .rodata.cst4,"aM",@progbits,4
.align 4
.LC0:
.long -981023877
.align 4
.LC1:
.long -1009239873
.align 4
.LC2:
.long 1083803959
.align 4
.LC3:
.long 1173804831
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3261 次 |
| 最近记录: |