最近读过在数值计算中fortran比c / c ++更快的主要原因是因为没有指针别名。
显然,使用restrict
或__restrict__
关键字允许根据具体情况来指示给定内存元素没有指针别名。
icc编译器显然有一个选项-fno-alias
,它允许全局假设不存在别名。在gcc上有-fno-strict-aliasing
,它仅适用于所有别名情况的子集。
在使用某些优化标志时,gcc中是否存在选项,或者是否存在未假设别名的情况?
答案 0 :(得分:15)
GCC具有选项-fstrict-aliasing
,可以全局启用别名优化,并期望你确保没有任何非法别名。我相信-O2
和-O3
已启用此优化。
C ++具有明确定义的别名规则,并且符合标准的代码不会与严格的别名冲突。特别是这意味着您不允许通过指向不同类型的指针访问一个变量:
float f;
int * p = reinterpret_cast<int*>(&f); // uh-oh
*p = 0x3FF00000; // breaks strict aliasing
此规则的关键例外是您始终可以通过指向char
的指针访问任何变量。 (这对于序列化IO操作是必要的。)
别名规则无法帮助编译器知道相同类型的任何指针是否相互别名。考虑一下:
void add(float * a, float * b, float * c) { *c = *a + *b; }
此处编译器无法知道c
是否指向与a
或b
不同的内存,必须小心。我认为这是restrict
产生影响的地方,主要是承诺float * restrict c
意味着没有人将c
别名。