寻觅生命中的那一片浅草......

每月存档 十一月, 2009

搭建CentOS5.3本地HTTP_YUM源

下载ISO,挂载
mount -o loop /export/CentOS-5.3-x86_64-bin-DVD.iso /media/
mkdir -p /var/www/html/CentOS5
cd /var/www/html/CentOS5
cp -a /media/* .

安装软件

yum -y install createrepo

生成xml文件
createrepo /var/www/html/CentOS5/CentOS
这样操作后 /var/www/html/CentOS5/CentOS下会多出一个repodata目录

如果要生成带group信息的也就是可以用yum grouplist或yum groupinstall的,则需要用以下命令

createrepo -g /var/www/html/CentOS5/repodata/comps.xml CentOS/

删除旧的repodate
rm -rf /var/www/html/CentOS5/repodata

假设你用的域名是www.example.com
假设你已经配置好Apache或Nginx,并可以通过http://www.example.com/访问到你的/var/www/html目录
编写CentOS5-HTTP.repo文件
vi CentOS5-HTTP.repo
[CentOS5-HTTP]
name=CentOS-$releasever – CentOS5-CentOS5-HTTP
baseurl=http://www.example.com/CentOS5/CentOS/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5

保存退出

将CentOS5-HTTP.repo分发到客户端
保存到
/etc/yum.repos.d/

测试安装lrzsz软件

yum –disablerepo=\* –enablerepo=CentOS5-HTTP -y install lrzsz

至此,配置完毕

解決64 位CPU compiler 時 zli出现/usr/local/lib/libz.a(crc32.o)造成的问题

/usr/bin/ld: /usr/local/lib/libz.a(crc32.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libz.a: could not read symbols: Bad value

解决方法如下:

cd zlib-1.2.3 //进入zlib目录
CFLAGS="-O3 -fPIC" ./configure   //使用64位元的方法进行编译
make
make install
make clean

GCC编译优化指南

GCC编译优化指南【作者:金步国】

版权声明

本文作者是一位自由软件爱好者,所以本文虽然不是软件,但是本着 GPL 的精神发布。任何人都可以自由使用、转载、复制和再分发,但必须保留作者署名,亦不得对声明中的任何条款作任何形式的修改,也不得附加任何其它条件。您可以自由链接、下载、传播此文档,但前提是必须保证全文完整转载,包括完整的版权信息和作译者声明。

其他作品

本文作者十分愿意与他人共享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有作品的列表:

BUG报告,切磋与探讨

由于作者水平有限,因此不能保证作品内容准确无误,请在阅读中自行鉴别。如果你发现了作品中的错误,请您来信指出,哪怕是错别字也好,任何提高作品质量的建议我都将虚心接纳。如果你愿意就作品中的相关内容与我进行进一步切磋与探讨,也欢迎你与我联系。联系方式:MSN: csfrank122@hotmail.com


前言

网上关于编译优化的文章很多,但大多零零散散,不成体系,本文试图给出一个完整和清晰的优化思路,同时提供在实践中如何进行优化的详尽参考。但是,在介绍所有优化知识之前首先引用LFS-Book中的一句忠告:“使用编译器优化得到的小幅度性能提升,与它带来的风险相比微不足道”。你还要进行优化吗?

%@&#=^%~*# …
OK, crazy guy! Let’s Go!!

在继续之前,作者还是奉劝各位:如果追求极致的优化,那么它将是一件既耗时又麻烦的事情,你会陷入无止尽的测试、测试、再测试……另外 Gentoo wiki 上有这么一句话:”GCC has well over a hundred individual optimization flags and it would be insane to try and describe them all.”所以本文不会涉及全部GCC优化选项。最后作者还是再罗唆一句:优化应当适可而止为好,将精力留出来做一些其它事情会更有意义!

先决条件

本文的主要读者是 LFS/Gentoo 的玩家,基本上比较 crazy 的玩家都接触过,如果你之前从未使用过 LFS/Gentoo ,请先按照《Linux From Scratch 6.2 中文版》做一遍 LFS ,然后再来阅读此文将会更有意义。另外,本文是建立在《深入理解软件包的配置、编译与安装》一文基础之上的,在开始阅读本文之前,请先阅读它。

基本原理

我们首先从三个方面来看与优化相关的内容:

  1. 从运行时的依赖关系来看,对性能有较大影响的组件有 kernel 和 glibc ,虽然这严格说来这不属于本文的话题,但是经过精心选择、精心配置、精心编译的内核与C库将对提高系统的运行速度起着基础性的作用。
  2. 从被编译的软件包来看,每个软件包的 configure 脚本都提供了许多配置选项,其中有许多选项是与性能息息相关的。比如,对于 Apache-2.2.6 而言,你可以使用 –enable-MODULE=static 将模块静态编译进核心,使用 –disable-MODULE 禁用不需要的模块,使用 –with-mpm=MPM 选择一个高效的多路处理模块,在不需要IPv6的情况下使用 –disable-ipv6 禁用IPv6支持,在不使用线程化的MPM时使用 –disable-threads 禁用线程支持,等等……这部分内容显然不可能在本文中进行完整的讲述,本文只能讲述与优化相关的通用选项。针对特定的软件包,请在编译前使用 configure –help 查看所有选项,并精心选择。
  3. 从编译过程自身来看,将源代码编译为二进制文件是在 Makefile 文件的指导下,由 make 程序调用一条条编译命令完成的。而将源代码编译为二进制文件又需要经过以下四个步骤:预处理(cpp) → 编译(gcc或g++) → 汇编(as) → 连接(ld) ;括号中表示每个阶段所使用的程序,它们分别属于 GCC 和 Binutils 软件包。显然的,优化应当从编译工具自身的选择以及控制编译工具的行为入手。

大体上编译优化就这”三板斧”(其实是”三脚猫”)了,本文接下来的内容将讨论这只猫的后两只脚。

编译工具的选择

对于编译工具自身的选择,在假定使用 Binutils 和 GCC 以及 Make 的前提下,没什么好说的,基本上新版本都能带来性能提升,同时比老版本对新硬件的支持更好,所以应当尽量选用新版本。不过追新也可能带来系统的不稳定,这就要针对实际情况进行权衡了。本文以 Binutils-2.18 和 GCC-4.2.2/GCC-4.3.0 以及 Make-3.81 为例进行说明。

configure 选项

这里我们只讲解通用的”体系结构选项”,由于”特性选项”在每个软件包之间千差万别,所以不可能在此处进行讲解。

这部分内容很简单,并且其含义也是不言而喻的,下面只列出常用的值:

  • i586-pc-linux-gnu
  • i686-pc-linux-gnu
  • x86_64-pc-linux-gnu
  • powerpc-unknown-linux-gnu
  • powerpc64-unknown-linux-gnu

如果你实在不知道应当使用哪一个,那么就干脆不使用这几个选项,让 config.guess 脚本自己去猜吧,反正也挺准的。

编译选项

让我们先看看 Makefile 规则中的编译命令通常是怎么写的。

大多数软件包遵守如下约定俗成的规范:

#1,首先从源代码生成目标文件(预处理,编译,汇编),"-c"选项表示不执行链接步骤。
$(CC) $(CPPFLAGS) $(CFLAGS) example.c   -c   -o example.o
#2,然后将目标文件连接为最终的结果(连接),"-o"选项用于指定输出文件的名字。
$(CC) $(LDFLAGS) example.o   -o example

#有一些软件包一次完成四个步骤:
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c   -o example

当然也有少数软件包不遵守这些约定俗成的规范,比如:

#1,有些在命令行中漏掉应有的Makefile变量(注意:有些遗漏是故意的)
$(CC) $(CFLAGS) example.c    -c   -o example.o
$(CC) $(CPPFLAGS) example.c  -c   -o example.o
$(CC) example.o   -o example
$(CC) example.c   -o example
#2,有些在命令行中增加了不必要的Makefile变量
$(CC) $(CFLAGS) $(LDFLAGS) example.o   -o example
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c   -c   -o example.o

当然还有极个别软件包完全是”胡来”:乱用变量(增加不必要的又漏掉了应有的)者有之,不用$(CC)者有之,不一而足…..

尽管将源代码编译为二进制文件的四个步骤由不同的程序(cpp,gcc/g++,as,ld)完成,但是事实上 cpp, as, ld 都是由 gcc/g++ 进行间接调用的。换句话说,控制了 gcc/g++ 就等于控制了所有四个步骤。从 Makefile 规则中的编译命令可以看出,编译工具的行为全靠 CC/CXX CPPFLAGS CFLAGS/CXXFLAGS LDFLAGS 这几个变量在控制。当然理论上控制编译工具行为的还应当有 AS ASFLAGS ARFLAGS 等变量,但是实践中基本上没有软件包使用它们。

那么我们如何控制这些变量呢?一种简易的做法是首先设置与这些 Makefile 变量同名的环境变量并将它们 export 为全局,然后运行 configure 脚本,大多数 configure 脚本会使用这同名的环境变量代替 Makefile 中的值。但是少数 configure 脚本并不这样做(比如GCC-3.4.6和Binutils-2.16.1的脚本就不传递LDFLAGS),你必须手动编辑生成的 Makefile 文件,在其中寻找这些变量并修改它们的值,许多源码包在每个子文件夹中都有 Makefile 文件,真是一件很累人的事!

CC 与 CXX

这是 C 与 C++ 编译器命令。默认值一般是 “gcc” 与 “g++”。这个变量本来与优化没有关系,但是有些人因为担心软件包不遵守那些约定俗成的规范,害怕自己苦心设置的 CFLAGS/CXXFLAGS/LDFLAGS 之类的变量被忽略了,而索性将原本应当放置在其它变量中的选项一股老儿塞到 CC 或 CXX 中,比如:CC=”gcc -march=k8 -O2 -s”。这是一种怪异的用法,本文不提倡这种做法,而是提倡按照变量本来的含义使用变量。

CPPFLAGS

这是用于预处理阶段的选项。不过能够用于此变量的选项,看不出有哪个与优化相关。如果你实在想设一个,那就使用下面这两个吧:

-DNDEBUG
“NDEBUG”是一个标准的 ANSI 宏,表示不进行调试编译。
-D_FILE_OFFSET_BITS=64
大多数包使用这个来提供大文件(>2G)支持。

CFLAGS 与 CXXFLAGS

CFLAGS 表示用于 C 编译器的选项,CXXFLAGS 表示用于 C++ 编译器的选项。这两个变量实际上涵盖了编译和汇编两个步骤。大多数程序和库在编译时默认的优化级别是”2″(使用”-O2″选项)并且带有调试符号来编译,也就是 CFLAGS=”-O2 -g”, CXXFLAGS=$CFLAGS 。事实上,”-O2″已经启用绝大多数安全的优化选项了。另一方面,由于大部分选项可以同时用于这两个变量,所以仅在最后讲述只能用于其中一个变量的选项。[提醒]下面所列选项皆为非默认选项,你只要按需添加即可。

先说说”-O3″在”-O2″基础上增加的几项:

-finline-functions
允许编译器选择某些简单的函数在其被调用处展开,比较安全的选项,特别是在CPU二级缓存较大时建议使用。
-funswitch-loops
将循环体中不改变值的变量移动到循环体之外。
-fgcse-after-reload
为了清除多余的溢出,在重载之后执行一个额外的载入消除步骤。

另外:

-fomit-frame-pointer
对于不需要栈指针的函数就不在寄存器中保存指针,因此可以忽略存储和检索地址的代码,同时对许多函数提供一个额外的寄存器。所有”-O”级别都打开它,但仅在调试器可以不依靠栈指针运行时才有效。在AMD64平台上此选项默认打开,但是在x86平台上则默认关闭。建议显式的设置它。
-falign-functions=N
-falign-jumps=N
-falign-loops=N
-falign-labels=N
这四个对齐选项在”-O2″中打开,其中的根据不同的平台N使用不同的默认值。如果你想指定不同于默认值的N,也可以单独指定。比如,对于L2-cache>=1M的cpu而言,指定 -falign-functions=64 可能会获得更好的性能。建议在指定了 -march 的时候不明确指定这里的值。

调试选项:

-fprofile-arcs
在使用这一选项编译程序并运行它以创建包含每个代码块的执行次数的文件后,程序可以再次使用 -fbranch-probabilities 编译,文件中的信息可以用来优化那些经常选取的分支。如果没有这些信息,gcc将猜测哪个分支将被经常运行以进行优化。这类优化信息将会存放在一个以源文件为名字的并以”.da”为后缀的文件中。

全局选项:

-pipe
在编译过程的不同阶段之间使用管道而非临时文件进行通信,可以加快编译速度。建议使用。

目录选项:

–sysroot=dir
将dir作为逻辑根目录。比如编译器通常会在 /usr/include 和 /usr/lib 中搜索头文件和库,使用这个选项后将在 dir/usr/include 和 dir/usr/lib 目录中搜索。如果使用这个选项的同时又使用了 -isysroot 选项,则此选项仅作用于库文件的搜索路径,而 -isysroot 选项将作用于头文件的搜索路径。这个选项与优化无关,但是在 CLFS 中有着神奇的作用。

代码生成选项:

-fno-bounds-check
关闭所有对数组访问的边界检查。该选项将提高数组索引的性能,但当超出数组边界时,可能会造成不可接受的行为。
-freg-struct-return
如果struct和union足够小就通过寄存器返回,这将提高较小结构的效率。如果不够小,无法容纳在一个寄存器中,将使用内存返回。建议仅在完全使用GCC编译的系统上才使用。
-fpic
生成可用于共享库的位置独立代码。所有的内部寻址均通过全局偏移表完成。要确定一个地址,需要将代码自身的内存位置作为表中一项插入。该选项产生可以在共享库中存放并从中加载的目标模块。
-fstack-check
为防止程序栈溢出而进行必要的检测,仅在多线程环境中运行时才可能需要它。
-fvisibility=hidden
设置默认的ELF镜像中符号的可见性为隐藏。使用这个特性可以非常充分的提高连接和加载共享库的性能,生成更加优化的代码,提供近乎完美的API输出和防止符号碰撞。我们强烈建议你在编译任何共享库的时候使用该选项。参见 -fvisibility-inlines-hidden 选项。

硬件体系结构相关选项[仅仅针对x86与x86_64]:

-march=cpu-type
为特定的cpu-type编译二进制代码(不能在更低级别的cpu上运行)。Intel可以用:pentium2, pentium3(=pentium3m), pentium4(=pentium4m), pentium-m, prescott, nocona, core2(GCC-4.3新增) 。AMD可以用:k6-2(=k6-3), athlon(=athlon-tbird), athlon-xp(=athlon-mp), k8(=opteron=athlon64=athlon-fx)
-mfpmath=sse
P3和athlon-xp级别及以上的cpu支持”sse”标量浮点指令。仅建议在P4和K8以上级别的处理器上使用该选项。
-malign-double
将double, long double, long long对齐于双字节边界上;有助于生成更高速的代码,但是程序的尺寸会变大,并且不能与未使用该选项编译的程序一起工作。
-m128bit-long-double
指定long double为128位,pentium以上的cpu更喜欢这种标准,并且符合x86-64的ABI标准,但是却不附合i386的ABI标准。
-mregparm=N
指定用于传递整数参数的寄存器数目(默认不使用寄存器)。0<=N<=3 ;注意:当N>0时你必须使用同一参数重新构建所有的模块,包括所有的库。
-msseregparm
使用SSE寄存器传递float和double参数和返回值。注意:当你使用了这个选项以后,你必须使用同一参数重新构建所有的模块,包括所有的库。
-mmmx
-msse
-msse2
-msse3
-m3dnow
-mssse3(没写错!GCC-4.3新增)
-msse4.1(GCC-4.3新增)
-msse4.2(GCC-4.3新增)
-msse4(含4.1和4.2,GCC-4.3新增)
是否使用相应的扩展指令集以及内置函数,按照自己的cpu选择吧!
-maccumulate-outgoing-args
指定在函数引导段中计算输出参数所需最大空间,这在大部分现代cpu中是较快的方法;缺点是会明显增加二进制文件尺寸。
-mthreads
支持Mingw32的线程安全异常处理。对于依赖于线程安全异常处理的程序,必须启用这个选项。使用这个选项时会定义”-D_MT”,它将包含使用选项”-lmingwthrd”连接的一个特殊的线程辅助库,用于为每个线程清理异常处理数据。
-minline-all-stringops
默认时GCC只将确定目的地会被对齐在至少4字节边界的字符串操作内联进程序代码。该选项启用更多的内联并且增加二进制文件的体积,但是可以提升依赖于高速 memcpy, strlen, memset 操作的程序的性能。
-minline-stringops-dynamically
GCC-4.3新增。对未知尺寸字符串的小块操作使用内联代码,而对大块操作仍然调用库函数,这是比”-minline-all-stringops”更聪明的策略。决定策略的算法可以通过”-mstringop-strategy”控制。
-momit-leaf-frame-pointer
不为叶子函数在寄存器中保存栈指针,这样可以节省寄存器,但是将会使调试变的困难。注意:不要与 -fomit-frame-pointer 同时使用,因为会造成代码效率低下。
-m64
生成专门运行于64位环境的代码,不能运行于32位环境,仅用于x86_64[含EMT64]环境。
-mcmodel=small
[默认值]程序和它的符号必须位于2GB以下的地址空间。指针仍然是64位。程序可以静态连接也可以动态连接。仅用于x86_64[含EMT64]环境。
-mcmodel=kernel
内核运行于2GB地址空间之外。在编译linux内核时必须使用该选项!仅用于x86_64[含EMT64]环境。
-mcmodel=medium
程序必须位于2GB以下的地址空间,但是它的符号可以位于任何地址空间。程序可以静态连接也可以动态连接。注意:共享库不能使用这个选项编译!仅用于x86_64[含EMT64]环境。

其它优化选项:

-fforce-addr
必须将地址复制到寄存器中才能对他们进行运算。由于所需地址通常在前面已经加载到寄存器中了,所以这个选项可以改进代码。
-finline-limit=n
对伪指令数超过n的函数,编译程序将不进行内联展开,默认为600。增大此值将增加编译时间和编译内存用量并且生成的二进制文件体积也会变大,此值不宜太大。
-fmerge-all-constants
试图将跨编译单元的所有常量值和数组合并在一个副本中。但是标准C/C++要求每个变量都必须有不同的存储位置,所以该选项可能会导致某些不兼容的行为。
-fgcse-sm
在全局公共子表达式消除之后运行存储移动,以试图将存储移出循环。gcc-3.4中曾属于”-O2″级别的选项。
-fgcse-las
在全局公共子表达式消除之后消除多余的在存储到同一存储区域之后的加载操作。gcc-3.4中曾属于”-O2″级别的选项。
-floop-optimize
已废除(GCC-4.1曾包含在”-O1″中)。
-floop-optimize2
使用改进版本的循环优化器代替原来”-floop-optimize”。该优化器将使用不同的选项(-funroll-loops, -fpeel-loops, -funswitch-loops, -ftree-loop-im)分别控制循环优化的不同方面。目前这个新版本的优化器尚在开发中,并且生成的代码质量并不比以前的版本高。已废除,仅存在于GCC-4.1之前的版本中。
-funsafe-loop-optimizations
假定循环不会溢出,并且循环的退出条件不是无穷。这将可以在一个比较广的范围内进行循环优化,即使优化器自己也不能断定这样做是否正确。
-fsched-spec-load
允许一些装载指令执行一些投机性的动作。
-ftree-loop-linear
在trees上进行线型循环转换。它能够改进缓冲性能并且允许进行更进一步的循环优化。
-fivopts
在trees上执行归纳变量优化。
-ftree-vectorize
在trees上执行循环向量化。
-ftracer
执行尾部复制以扩大超级块的尺寸,它简化了函数控制流,从而允许其它的优化措施做的更好。据说挺有效。
-funroll-loops
仅对循环次数能够在编译时或运行时确定的循环进行展开,生成的代码尺寸将变大,执行速度可能变快也可能变慢。
-fprefetch-loop-arrays
生成数组预读取指令,对于使用巨大数组的程序可以加快代码执行速度,适合数据库相关的大型软件等。具体效果如何取决于代码。
-fweb
建立经常使用的缓存器网络,提供更佳的缓存器使用率。gcc-3.4中曾属于”-O3″级别的选项。
-ffast-math
违反IEEE/ANSI标准以提高浮点数计算速度,是个危险的选项,仅在编译不需要严格遵守IEEE规范且浮点计算密集的程序考虑采用。
-fsingle-precision-constant
将浮点常量作为单精度常量对待,而不是隐式地将其转换为双精度。
-fbranch-probabilities
在使用 -fprofile-arcs 选项编译程序并执行它来创建包含每个代码块执行次数的文件之后,程序可以利用这一选项再次编译,文件中所产生的信息将被用来优化那些经常发生的分支代码。如果没有这些信息,gcc将猜测那一分支可能经常发生并进行优化。这类优化信息将会存放在一个以源文件为名字的并以”.da”为后缀的文件中。
-frename-registers
试图驱除代码中的假依赖关系,这个选项对具有大量寄存器的机器很有效。gcc-3.4中曾属于”-O3″级别的选项。
-fbranch-target-load-optimize
-fbranch-target-load-optimize2
在执行序启动以及结尾之前执行分支目标缓存器加载最佳化。
-fstack-protector
在关键函数的堆栈中设置保护值。在返回地址和返回值之前,都将验证这个保护值。如果出现了缓冲区溢出,保护值不再匹配,程序就会退出。程序每次运行,保护值都是随机的,因此不会被远程猜出。
-fstack-protector-all
同上,但是在所有函数的堆栈中设置保护值。
–param max-gcse-memory=xxM
执行GCSE优化使用的最大内存量(xxM),太小将使该优化无法进行,默认为50M。
–param max-gcse-passes=n
执行GCSE优化的最大迭代次数,默认为 1。

传递给汇编器的选项:

-Wa,options
options是一个或多个由逗号分隔的可以传递给汇编器的选项列表。其中的每一个均可作为命令行选项传递给汇编器。
-Wa,–strip-local-absolute
从输出符号表中移除局部绝对符号。
-Wa,-R
合并数据段和正文段,因为不必在数据段和代码段之间转移,所以它可能会产生更短的地址移动。
-Wa,–64
设置字长为64bit,仅用于x86_64,并且仅对ELF格式的目标文件有效。此外,还需要使用”–enable-64-bit-bfd”选项编译的BFD支持。
-Wa,-march=CPU
按照特定的CPU进行优化:pentiumiii, pentium4, prescott, nocona, core, core2; athlon, sledgehammer, opteron, k8 。

仅可用于 CFLAGS 的选项:

-fhosted
按宿主环境编译,其中需要有完整的标准库,入口必须是main()函数且具有int型的返回值。内核以外几乎所有的程序都是如此。该选项隐含设置了 -fbuiltin,且与 -fno-freestanding 等价。
-ffreestanding
按独立环境编译,该环境可以没有标准库,且对main()函数没有要求。最典型的例子就是操作系统内核。该选项隐含设置了 -fno-builtin,且与 -fno-hosted 等价。

仅可用于 CXXFLAGS 的选项:

-fno-enforce-eh-specs
C++标准要求强制检查异常违例,但是该选项可以关闭违例检查,从而减小生成代码的体积。该选项类似于定义了”NDEBUG”宏。
-fno-rtti
如果没有使用’dynamic_cast’和’typeid’,可以使用这个选项禁止为包含虚方法的类生成运行时表示代码,从而节约空间。此选项对于异常处理无效(仍然按需生成rtti代码)。
-ftemplate-depth-n
将最大模版实例化深度设为’n’,符合标准的程序不能超过17,默认值为500。
-fno-optional-diags
禁止输出诊断消息,C++标准并不需要这些消息。
-fno-threadsafe-statics
GCC自动在访问C++局部静态变量的代码上加锁,以保证线程安全。如果你不需要线程安全,可以使用这个选项。
-fvisibility-inlines-hidden
默认隐藏所有内联函数,从而减小导出符号表的大小,既能缩减文件的大小,还能提高运行性能,我们强烈建议你在编译任何共享库的时候使用该选项。参见 -fvisibility=hidden 选项。

LDFLAGS

LDFLAGS 是传递给连接器的选项。这是一个常被忽视的变量,事实上它对优化的影响也是很明显的。

[提示]以下选项是在完整的阅读了ld-2.18文档之后挑选出来的选项。http://blog.chinaunix.net/u1/41220/showart_354602.html 有2.14版本的中文手册。

-s
删除可执行程序中的所有符号表和所有重定位信息。其结果与运行命令 strip 所达到的效果相同,这个选项是比较安全的。
-Wl,options
options是由一个或多个逗号分隔的传递给链接器的选项列表。其中的每一个选项均会作为命令行选项提供给链接器。
-Wl,-On
当n>0时将会优化输出,但是会明显增加连接操作的时间,这个选项是比较安全的。
-Wl,–exclude-libs=ALL
不自动导出库中的符号,也就是默认将库中的符号隐藏。
-Wl,-m<emulation>
仿真<emulation>连接器,当前ld所有可用的仿真可以通过”ld -V”命令获取。默认值取决于ld的编译时配置。
-Wl,–sort-common
把全局公共符号按照大小排序后放到适当的输出节,以防止符号间因为排布限制而出现间隙。
-Wl,-x
删除所有的本地符号。
-Wl,-X
删除所有的临时本地符号。对于大多数目标平台,就是所有的名字以’L’开头的本地符号。
-Wl,-zcomberloc
组合多个重定位节并重新排布它们,以便让动态符号可以被缓存。
-Wl,–enable-new-dtags
在ELF中创建新式的”dynamic tags”,但在老式的ELF系统上无法识别。
-Wl,–as-needed
移除不必要的符号引用,仅在实际需要的时候才连接,可以生成更高效的代码。
-Wl,–no-define-common
限制对普通符号的地址分配。该选项允许那些从共享库中引用的普通符号只在主程序中被分配地址。这会消除在共享库中的无用的副本的空间,同时也防止了在有多个指定了搜索路径的动态模块在进行运行时符号解析时引起的混乱。
-Wl,–hash-style=gnu
使用gnu风格的符号散列表格式。它的动态链接性能比传统的sysv风格(默认)有较大提升,但是它生成的可执行程序和库与旧的Glibc以及动态链接器不兼容。

最后说两个与优化无关的系统环境变量,因为会影响GCC编译程序的方式,下面两个是咱中国人比较关心的:

LANG
指定编译程序使用的字符集,可用于创建宽字符文件、串文字、注释;默认为英文。[目前只支持日文”C-JIS,C-SJIS,C-EUCJP”,不支持中文]
LC_ALL
指定多字节字符的字符分类,主要用于确定字符串的字符边界以及编译程序使用何种语言发出诊断消息;默认设置与LANG相同。中文相关的几项:”zh_CN.GB2312 , zh_CN.GB18030 , zh_CN.GBK , zh_CN.UTF-8 , zh_TW.BIG5″。

转载自:http://lamp.linux.gov.cn/Linux/optimize_guide.html

SysAdmin to SysAdmin: Making use of SNMP

“Simple Network Management Protocol” is a relative term. To the uninitiated, raw SNMP output, along with arcane technobabble like “MIB” and “ASN.1,” looks a little daunting. Developing some understanding of how to parse and filter SNMP information doesn’t take long, though, and can put you on a fast track to making SNMP bend to your whim.

The first thing to know about SNMP is that it is a service that is structured such that an SNMP agent sitting on a target host can be queried by remote hosts for various bits of information. Only the target host (the one you want information about) needs to be running an SNMP daemon. The client making the queries just needs some tool capable of making SNMP queries and parsing the output. Most Linux server and client tools are supplied by the Net-SNMP project. A quick poke around your system to locate snmpwalk or snmpget should let you know in short order if you have the client tools installed. The server daemon is called, predictably, snmpd.

The easiest way to get familiar with how SNMP works is to set it up on your own Linux system. Since this might be the piece of machinery with which you are also the most familiar, it’ll also be a great way to see the sheer power of SNMP. Since most Linux distributions come with a Net-SNMP daemon, I’m going to forgo discussing installation and head right to configuration.

Configuring snmpd

If you maintain a lot of services, you’re probably tired of having to remember which directive handles what in all of the differently formatted config files. Apache, BIND, Sendmail, LDAP, NIS, NFS, and SSH all have different formats — and that’s just the beginning. You’ll be relieved to know that SNMP has a really great configuration tool called snmpconf. Veteran sysadmins will be happy to know that this is a command-line tool. New admins will have to suck it up!

Seriously, though, if you just want to get a very quick configuration put together, try running snmpconf -g basic_setup, and you’ll be able to set up what you need in order to see what the daemon has to offer. For those who have more than three minutes on their hands and want more control over the configuration, simply running snmpconf will prompt you with menus to configure the different aspects of the running daemon. The questions are very easy and completely self-explanatory (I’d even venture to say elementary) for any Linux or Unix sysadmin. Once you finish, move the resulting snmpd.conf file into place, and start the snmpd daemon.

Once the daemon is started, try pasting this into your terminal and pressing Enter: snmpwalk -v2c -c public localhost tcp. Here’s some output from my laptop:

TCP-MIB::tcpConnState.0.0.0.0.22.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.0.0.0.0.111.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.0.0.0.0.199.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.0.0.0.0.32768.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.127.0.0.1.25.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.127.0.0.1.631.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.127.0.0.1.32769.0.0.0.0.0 = INTEGER: listen(2)
TCP-MIB::tcpConnState.127.0.0.1.32776.127.0.0.1.631 = INTEGER: closeWait(8)

This is just a chunk of output, and as you can probably discern, it’s telling me which ports I have open (they’re in state “listen”). For the record, recent Net-SNMP packages come with a command called snmpnetstat that does this and more for you. But the point is that SNMP can tell you just about anything you want to know about the running system, but this output doesn’t reveal very much about SNMP itself.

Let’s alter the command like this: snmpwalk -On -v2c -c public localhost tcp. The -On flag tells the client to return the numeric OID or object ID string instead of abbreviating it using the MIB used to parse said OID. What’s an OID? Glad you asked. Let’s look at the output:

.1.3.6.1.2.1.6.13.1.1.0.0.0.0.22.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.0.0.0.0.111.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.0.0.0.0.199.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.0.0.0.0.32768.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.127.0.0.1.25.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.127.0.0.1.631.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.127.0.0.1.32769.0.0.0.0.0 = INTEGER: listen(2)
.1.3.6.1.2.1.6.13.1.1.127.0.0.1.32776.127.0.0.1.631 = INTEGER: closeWait(8)

My favorite output flag, though, is -Of, which parses each of the numbers above into a human-readable (if very long) name.

The OID in the above output is everything before the equals-sign. It’s called an object ID because SNMP stores every piece of data as an object. Furthermore, those objects are identified internally as numbers, which get parsed into names on the client side, using a Management Information Base (MIB) file. A MIB is a human-readable text file which is actually extremely handy, since it contains all of the descriptions for the different pieces of data returned. If you’re not sure if a particular piece of data is what you’re looking for, heading for the MIB file that parsed it is usually a good way to find the answer.

For example, in the first output listing, you can see something called “tcpConnState.” At the very beginning of each line, you also see “TCP-MIB.” If you want to see a better description of what this value really means, you need to find a file on your system called TCP-MIB.txt; on my Fedora Core 2 machine, MIBs are in /usr/share/snmp/mibs. grep for “tcpConnState” in the file, and scroll down to the description to see what it says. NOTE: Descriptions aren’t always useful. Generally, though, the standard MIBs (i.e., not vendor-supplied ones) are good enough to get a clue.

So what’s with the long numbers as OIDs? That’s ASN.1 notation. Abstract Syntax Notation provides a standard way of describing data independent of any language or application. Agents are written to provide data using ASN.1, and client applications are written to handle that data in any language and in any way the developers see fit. The goal is generalization, and it would appear that it works. LDAP and SNMP both use ASN.1 notation, and the tools built around these two protocols (snmpwalk, ldapsearch, etc.) handle the task of making the output readable by humans. In LDAP parlance, a MIB is called a “schema.” The rest is very similar from a data representation perspective.

For SNMP data (as well as LDAP), the ASN.1 numbers actually represent a hierarchical structure — similar to the way the directory on your system is hierarchical in nature. In fact, you could look at the numeric output above, and think of .1 as the / or root directory. The fact that it’s followed by a 3 would seem to imply that there are at least two other nodes under that top-level node, and you’d be right in assuming that. The same goes for all of the numbers all the way down the line. In fact, you could think of the command snmpwalk -Of -v2c -c public localhost tcp as simply running ls -lR on the tcp directory within the hierarchy.

What SNMP can do for you

Here are some quick one-liners that illustrate some cool stuff about your system. These were tested on my FC2 laptop, as well as a SUSE 9.1 workstation:

* snmpwalk -Ov -OQ -v2c -c public localhost .1.3.6.1.2.1.25.6.3.1.2

This lists the names of every installed package on the machine. It essentially does the same thing as rpm -qa on an RPM-based distro, but it’s slightly easier to grab the information from a remote location using SNMP. There are lots of those -O flags available. The O stands for “output,” and you can stack them as I’ve done here in order to strip out everything but the actual value. For more on this, see the snmpcmd manpage.
* snmpwalk -Of -v2c -c public localhost interfaces | grep “.2 =”

This walks the interfaces directory and grabs anything pertaining to what amounts to “interface 2.” The interfaces are indexed numerically, and interface 1 is generally the loopback. For each interface, a host of values is displayed, so if you run something like this on a huge switch and aggregate and parse the data, you can create some extremely useful data.
* snmpwalk -OQ -Ov -v2c -c public localhost .1.3.6.1.2.1.25.4.2.1.2

This gets you a quick list of the programs running on a remote (or in this case, a local) host. The processes are also indexed, and you can get other information about them if you want to do a little scripting.

Plenty more where this came from

This is the tip of the iceberg. For avid scripters, I’ve used both the Perl and PHP SNMP interfaces, and both are immensely useful. Also, don’t think that SNMP is limited in use to Linux boxen; SNMP agents have been written for everything from large UPS units to tiny humidity sensors that’ll send a trap if your machine room starts to resemble a swampland. If there’s something in your environment with an Ethernet jack on it, there’s probably an SNMP agent for it.

I haven’t even mentioned the notion of actually making configuration changes via the snmpset command, but I urge you to investigate it for yourself. There’s a whole SNMP world out there waiting for you, and taking advantage of it can make your life as an administrator infinitely easier.

转载自:http://www.linux.com/archive/articles/113774

小牛怀旧恶搞版华农百年校庆

11月8日,是母校百年华诞。有些同学7号已经回到了广州,7号晚在岑村肥仔烧排骨吃了些农家菜,哈。由于部分同学起到比较晚,故8号早上十点多才从岑村出发去华农,但从早上开始,就电话不断,有打进来问去到哪里的,有打出去问校庆来不来,什么时候过来的。
一直不太认同华农有100年,只需看下最古老的农学院最早毕业的一届学生是52年的就知道了。但无论怎样,很多同学回来,为了聚聚,还是决定去了,见到了许多许久不见的同学,我们班,隔壁班的。还见到了很多白发苍苍的校友,母校还专门为每一位回来的校友发了个校友证。
和同学们漫步于校园,感受着它巨大的变化:搬迁了的农学院院楼,新建的牌坊,校行政大楼,复建的红满堂,曾在其上踢了无数球赛的黑山操场变成了湖,看着这些,想起了属于我们的五山公寓,用于来往校本部和五山公寓的自行车,华山学生公寓,我们的教一,教二,教三,还有农学院院楼。
在校庆典礼上,作为06届最优秀的毕业班,我们班有几个同学有幸作了重要讲话和奉献。

首先,当然是我们国家吹水总局局长江JJ了,江局长指出,自古以来,农民就有一边吹水一边耕田的优良传统,而华农发扬光大了这一优良传统,将吹水和耕田进行了有机的结合,吹水是大学教育的一部分,加快吹水教育的发展是大学走向综合性的充分体现,对于维护改革、发展、稳定大局具有重要意义。通过加强吹水教育,可以更好地增强大学生的体质和促进心理健康发展,培养出适合社会主义现代化建设的综合性高素质人才。
其次是我们贤弟,他贡献了他的虾#.net 3.0的源代码给母校作研究之用,同时,他也发表了题为《虾#.net在农业信息技术应用中的研究》的讲话,研究的成果是相当丰富的,通过研究发现,在虾养殖中使用虾#.net的for循环,可显著增加虾的产量,但这会产生负载过高导致过热的问题,贤弟指出,在虾#.net 4.5版本中,采用了全宇宙最先进的算法,将这技术难关攻克了。
第三是我们MJ professor了,他贡献了他大学四年来刻录的上万张盗版光盘,其中最多的是各种版本的Windows XP,有上海政府泄漏VLK版,番茄花园 V1.2V3.6,雨林木风精简优化完美版,值得深入的深度技术版,JUJU猫论坛特别版,电脑城装机Ghost集成驱动版。除了这些,还有Windows 2000专业版,Windows 2000高级服务器版,DOS 7.2,Linux方面有RedHat 9.0 DVD版,Fedora Core4.0,knoppix live CD版。UNIX方面有freebsd 5.0。MJ算是我电脑方面的启蒙老师,记得我把电脑带到广州,第一个XP系统(在家里用98)就是他帮忙装的,很遗憾,他把系统装到了最后一个分区,也就是F盘。
第四是我们102恶人谷面馆老板兼大厨桃哥了,他将他当年煮面用的西施煲,电热杯,锅铲,锅盖等送给了母校博物馆,这些物品,见证了老一辈华农人艰苦求学的岁月,校领导指出,这都很有教育意义,事实证明,在宿舍使用高功率电器完全没问题。

第五是王海尚同学宣布,他结婚了!祝他和他老婆百年好合,早生贵子,三年抱俩!

下面是一些琐碎的事了,老牛贡献了他的德生牌BCL 2000收音机,当年用来收听VOA,BBC的喔!地主从遥远的武汉说了句妈妈屁。瓜总推销了下他的易话宝。
大概也就这样了,本日志走的是怀旧+恶搞+怀旧路线,下面再怀旧下,大二团日活动班刊中关于咱们班宿舍的描述,怀旧下吧,我们的青葱岁月。

宿舍介绍
C1-706,是在农学院与园艺学院两院领导的关心与支持下产生的。本着“加强合作,相互促进”的宗旨;两院共同建设706宿舍为有理想,有文化,有道德,有修养的“四有”现代化宿舍。宿舍四人,各独挡一面,伍哥的理想是“热爱摇滚,热爱生活,热爱摇滚生活”。只要看他吉他不离手便知,而文化建设方面,则是肥均的拿手好戏,坚持两手抓,两手都要硬是他的座右铭!

C1-707,记得以前有只药胶布叫七零七,对腰酸背痛,风湿骨痛,肌肉疼痛有明显疗效。而精明且正直的黄教授正如707,将舍下之人治得服服帖帖。他们坚持天天早上扫地,拖地。晚上十一点准时关灯,晚修时间埋头苦读的良好习惯,实为农(2)班学习之楷模!

C1-708,准确地说应该是廖畅708.com,是咱班最和谐,协调之宿舍!何解?皆因他们宿舍有一个看足球赛而不踢球的肥江,有踢球不看球的老鸟,有既踢球又对当今足坛之风起云涌了如指掌的小鸟,还有既不看球也不踢球的小江。由以上事件得证:708不愧为阴阳调和之典范!老鸟实为一奇人,如果你问他日子怎过?他会告诉你,在足球的翻滚中慢慢流逝。也难怪,他能从早上的黄金时间六点(俗话说一天之计在于晨),踢球踢到晚上的钻石时间――还是六点。吾辈岂可望其项背!

C1-709,曾被某某协会授予“中国最牛宿舍”之光荣称号。只因那号称“中国第一牛”的牛了入住了该寝室,令到蓬荜生辉,斯是陋室,便有牛则灵。其实709原有四杰,今已去一,只剩其三,一乃上述牛了,二乃深谙计算机科学的老板,三乃看无数小说,引无数少女竟折腰的人如其名的帅哥!
C1-710,传闻中710养了一头牛,没错,那头牛就是我们的奶牛阿宋。阿宋每天工作得像牛一样,早出晚归,是个金牌兼职人员。宿舍中还有阿树,我们的团支书,同时也是个很神,很能吹水的人;海尚是我们足球队一个很好的中锋,吴君能言善辩,与谁都聊得来。

A2-438,真是个敏感的数字,每次别人问起房号,该宿舍成员都得集十万分的精神把这三个数字准确地念出。说到这四位成员,在班上男生眼中,是出了名的冷漠派,不过如果有机会到她们宿舍看看,那风风火火的嬉笑戏打场面一定会把男生们吓一跳的。

A2-439,其实此寝室是咱班公认的华农的中南海,兼中关村。农学院学生会仅有的几个部长中,竟有其4落户于此,这并不是命运之神的特别眷顾,而是她们不爱红妆爱武装打拼的结果!

A2-440,纵观本班的经典组合,非440莫属,她们的标志性出场仪式是:在上课铃声响过后5分钟内,鱼贯而入的四位妙龄女子,便是也!开学初某周四的体育谭闲谈中,大家猛然惊觉由于星期五的任课老师出差,整天没课,加上周末,只要再逃了星期一的英语课便可有整整五天的假期,于是大家便开始憧憬计划到哪玩。有的说要去珠海,深圳等等。当然,都只是说说聊以慰藉“苦闷的校园生活”而已,没有人当真。可当下午英语课440集体失踪时,便觉得事有蹊跷。当天晚上回到宿舍才得知440集团已经在前往桂林的火车上了!!!MY GOD!!!从早上到晚上不超过十个小时的时间内,440便完成了从决定,计划到买票,打包行李,上车的任务。其敢说敢做的疯狂劲可见一斑!

女生有13人为何只看到四个宿舍呢?
哦,在A1-212里,还有一个人,A1-212:我们鲁真可谓是“饮”中豪杰,酒量比很男生都要好。不过溺酒伤肝,劝适可而止。

2009年十一月
« 10月   12月 »
 1
2345678
9101112131415
16171819202122
23242526272829
30