最近读到fortran在数值计算中比c/c++快的主要原因是没有指针混叠。
显然,使用restrict
或__restrict__
关键字可以逐个表示给定内存元素没有指针混叠。
icc编译器显然有一个选项-fno-alias
,它允许全局假设没有混叠存在。在gcc上有-fno-strict-aliasing
,它只适用于所有混叠情况的一个子集。
在使用某些优化标志时,gcc中是否存在一个选项,或者在某些情况下假设没有混叠?
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
。