个人理解
别名:多个变量指向同一块内存区域时,这些变量互为别名
目前CPU都是多核,现代的指令体系都是并行、乱序执行。编译器为了充分利用硬件资源提升程序性能,编译时要分析指令、数据间的依赖关系,没有依赖关系的指令、数据访问可以并发乱序进行。
在分析依赖关系时别名就是一个绕不开的问题,究竟谁是谁的别名,如果编译器不清楚,那为了保证编译出的程序的正确性,只能做最坏打算,不确定的地方假定都是别名。
后来编译器定义了一些规则,符合什么条件的变量才可能是别名,不符合的绝对不会是别名。通过编译选项 strict-aliasing可以通知编译器,我的代码严格遵守这些规则,放心大胆的优化。
通过编译选项no-strict-aliasing可以通知编译器,我代码中有各种风骚的类型转换,你优化时悠着点,做好最坏的打算。
验证
代码如下
main.c1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #include <stdio.h> #include <stdint.h>
static int anint;
static void bar(int data) { printf("data is %u\n", data); } static void foo(double *dblptr) { anint=1; *dblptr=3.14159;
bar(anint); } int main(int argc, char *argv[]) { foo((double *) &anint); return 0; }
|
命令脚本如下
cmd1.sh1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #!/bin/bash
rm -f test-*
gcc -g -O2 -fstrict-aliasing main.c -o test-strict-alias gcc -g -O2 -fno-strict-aliasing main.c -o test-no-strict-alias
echo "-----strict-alias---" ./test-strict-alias
echo "-----no-strict-alias---" ./test-no-strict-alias
|
执行结果
output11 2 3 4 5
| -----strict-alias--- data is 1 -----no-strict-alias--- data is 4028335726
|
补充说明
实测时,O2优化级别以下的编译,-fstrict-aliasing 和 -fno-strict-aliasing运行结果一样。推测是编译器编译时没有打乱指令顺序,所以二者一致。
参考资料