linux – -O2优化打破了某些机器上的C代码
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了linux – -O2优化打破了某些机器上的C代码,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4931字,纯文字阅读大概需要8分钟。
内容图文
![linux – -O2优化打破了某些机器上的C代码](/upload/InfoBanner/zyjiaocheng/955/09df4af77e3e420cbe0828730c85b11d.jpg)
我有3台不同的机器,配置如下:
> OpenSuSe 12.1,linux内核3.1.10,gcc 4.6.2
> Debian 6,linux内核2.6.32,gcc 4.4.5
> CentOS 5.6,linux内核2.6.18,gcc 4.1.2
他们所有的架构都是x86_64.请注意,CentOS的软件版本比Debian更旧,但OpenSuSe软件的版本比Debian版本更新.
我有以下示例代码:
#include <cstdio>
#include <cstdlib>
unsigned int cols=5;
unsigned int rows=6;
int main()
{
//allocating...
double **mat=new double*[rows];
double *col=new double[rows];
for(unsigned int i=0;i<rows;++i)
{
mat[i]=new double[cols];
}
//filling with something...
for(unsigned int i=0;i<rows;++i)
{
for(unsigned int j=0;j<cols;++j)
{
mat[i][j]=i+j;
}
}
//testing...
unsigned long long sum,add;
for(unsigned int i=0;i<cols;++i)
{
sum=0;
for(unsigned int j=0;j<rows;++j)
{
col[j]=mat[j][i];
add=*((unsigned long long*) (&(col[j])));
sum+=add;
}
printf("%llu\n",sum);
}
return 0;
}
如果我编译此代码没有任何选项:
g++ code.cpp
它在所有机器上以相同的方式运行.
但是如果我用-O2编译它,它在第一台和第三台机器上的行为方式相同,但在第二台机器(Debian)上,-O2优化打破了它.
这是带有-O2的第一台机器上此代码的输出:
4619567317775286272
9238008735643729920
9250393634618998784
9259400833873739776
9266719183268216832
这是在带有-O2的第二台机器上:
0
4619567317775286272
9238008735643729920
9250393634618998784
9259400833873739776
第二台机器的输出看起来像第一个’输出,向下移动一行.
如果我用(&(mat [j] [i]))替换(&(col [j])),代码开始正常工作.
以下是第二台机器上带-v和-O2选项的编译器输出:
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)
COLLECT_GCC_OPTIONS='-v' '-O2' '-shared-libgcc' '-mtune=generic'
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/cc1plus -quiet -v -D_GNU_SOURCE dmtest.cpp -quiet -dumpbase dmtest.cpp -mtune=generic -auxbase dmtest -O2 -version -o /tmp/cc6v7CNY.s
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../x86_64-linux-gnu/include"
ignoring nonexistent directory "/usr/include/x86_64-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/4.4
/usr/include/c++/4.4/x86_64-linux-gnu
/usr/include/c++/4.4/backward
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include-fixed
/usr/include
End of search list.
GNU C++ (Debian 4.4.5-8) version 4.4.5 (x86_64-linux-gnu)
compiled by GNU C version 4.4.5, GMP version 4.3.2, MPFR version 3.0.0-p3.
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 5a2e15051eaa06a84cf6320b754ba993
COLLECT_GCC_OPTIONS='-v' '-O2' '-shared-libgcc' '-mtune=generic'
as -V -Qy -o /tmp/ccL37GHG.o /tmp/cc6v7CNY.s
GNU assembler version 2.20.1 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.20.1-system.20100303
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-O2' '-shared-libgcc' '-mtune=generic'
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2 --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5 -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. /tmp/ccL37GHG.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o
这种行为的原因是什么?我的代码是不正确的还是gcc 4.4.5中的错误?
解决方法:
根据this blog entry,GCC 4.4对-O2强制执行严格的别名规则.因此,类型惩罚访问会导致未定义的行为.不幸的是,为了获得打破严格别名规则的警告,你必须使用-Wstrict-aliasing进行编译.
也许较新版本的GCC已经恢复旧的行为,并决定是否为用户启用严格别名.
内容总结
以上是互联网集市为您收集整理的linux – -O2优化打破了某些机器上的C代码全部内容,希望文章能够帮你解决linux – -O2优化打破了某些机器上的C代码所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。