我有一个包含许多小内联函数的头文件。他们中的大多数碰巧都有固定的数据。由于这些函数的性能非常重要,因此它们处理常量的方式变得非常重要。AFAIK有两种方法来引用常量:
1)在一个单独的源文件中定义它们,该源文件稍后将与应用程序链接。
2)定义原地常量。
我会选择后一种方式,因为它更易于维护。但是,如果编译器不优化通过内联创建的数千个相等的常量,那么它可能会慢一些。
问题:
编译器会合并这些相同的常量吗?具体而言,将采用下列哪一种方法?
( 1)在编译单元之间合并相等的常数。
( 2)连接模块(整个程序或库)中的等量组合。
3)将常量与任何具有相同位模式的静态常量数据组合起来,满足编译单元或整个程序的对齐要求。
我使用现代编译器(GCC4.5)。
我不是汇编程序专家,因此我自己无法用几个简单的测试来回答这个问题:)
编辑:
常量相当大(其中大多数至少有16个字节),所以编译器不能立即为它们设置值。
EDIT2:
代码示例
这个地方使用常量:
float_4 sign(float_4 a)
{
const __attribute__((aligned(16))) float mask[4] = { //I use a macro for this line
0x80000000, 0x80000000, 0x80000000, 0x80000000};
const int128 mask = load(mask);
return b_and(a, mask);
}发布于 2011-02-15 22:47:09
根据GCC,下面的选项可以满足您的需要:
-fmerge-常数试图在编译单元之间合并相同的常量(字符串常量和浮点常数)。如果汇编程序和链接器支持该选项,则此选项是优化编译的默认选项。使用-fno-合并常量来抑制这种行为. 已在-O、-O2、-O3、-Os级别启用。
发布于 2011-02-15 22:45:35
如果在头文件中定义常量,如下所示:
int const TEN = 10;
// or
enum { ELEVEN = 11 };也就是说,在编译翻译单元( .cc源文件)时,不仅常量声明,而且定义对编译器也是可见的,然后编译器当然会在未启用优化的情况下用生成的代码中的常量值替换它。
[max@truth test]$ cat test.cc
int const TEN = 10; // definition available
extern int const TWELVE; // only declaration
int foo(int x) { return x + TEN; }
int bar(int x) { return x + TWELVE; }
[max@truth test]$ g++ -S -o - test.cc | c++filt | egrep -v " *\."
foo(int):
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl -4(%rbp), %eax
addl $10, %eax
leave
ret
bar(int):
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
movl TWELVE(%rip), %eax
addl -4(%rbp), %eax
leave
ret
TEN:注意,在foo(int)中,它是如何以addl $10, %eax的形式进行加法的,即用它的值替换十个常量。另一方面,在bar(int)中,它首先执行movl TWELVE(%rip), %eax将12的值从内存加载到eax寄存器(地址将由链接器解析),然后执行添加addl -4(%rbp), %eax。
优化的版本如下所示:
[max@truth test]$ g++ -O3 -S -o - test.cc | c++filt | egrep -v " *\."
foo(int):
leal 10(%rdi), %eax
ret
bar(int):
movl TWELVE(%rip), %eax
addl %edi, %eax
ret发布于 2011-02-15 22:50:33
我不认为你的问题有一般的答案。我只为C提供一个,C++的规则是不同的。
这在很大程度上取决于常量的类型。一个重要的类是“整数常量表达式”。它们可以在编译时确定,特别是用作“整数枚举常量”的值。你可以随时使用它。
enum { myFavoriteDimension = 55/2 };对于这样的常量,最好的情况通常应该发生:它们是作为汇编程序直接实现的。它们甚至没有存储位置,直接写入汇编程序,您的问题甚至没有意义。
对于其他数据类型,这个问题更为微妙。尝试强制不使用"const限定变量“的地址。这可以用register关键字来完成。
register double const something = 5.7;可能具有与上述相同的效果。
对于组合类型(struct、union、数组),没有通用的答案或方法。我已经看到gcc能够完全优化小阵列(大约10个元件)。
https://stackoverflow.com/questions/5010216
复制相似问题