摘要
本文着重介绍在不同的硬件环境下给GCC指定哪些参数才可以得到最佳的性能。
这篇文章是从一个名为Gentoo Linux的发行版的编程说明书里面分离出来的,希望对大家编译程序有帮助。
出处:
--------------------------------------------------------------------
一、1.2版(gcc 2.9.x版)
i386 (Intel), do you really want to install gentoo on that?
CHOST="i386-pc-linux-gnu"
CFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
i486 (Intel), do you really want to install gentoo on that?
CHOST="i486-pc-linux-gnu"
CFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
Pentium, Pentium MMX+, Celeron (Mendocino) (Intel)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
Pentium Pro/II/III/4, Celeron (Coppermine), Celeron (Willamette?) (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=i686 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i686 -O3 -pipe -fomit-frame-pointer"
Eden C3/Ezra (Via)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=i586 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i586 -O3 -pipe -fomit-frame-pointer"
Quote : I did the original gentoo install using 1.2, with gcc 2.95 using -march=i586. i686 won't work.
K6 or beyond (AMD)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
(A Duron will report "Athlon" in its /proc/cpuinfo)
Athlon (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
For the following, i don't know of any flag that enhance performances..., do you ?
PowerPC
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
Sparc
CHOST="sparc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
Sparc 64
CHOST="sparc64-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
二、1.4版(gcc 3.x版):
i386 (Intel), do you really want to install gentoo on that ?
CHOST="i386-pc-linux-gnu"
CFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i386 -O3 -pipe -fomit-frame-pointer"
i486 (Intel), do you really want to install gentoo on that ?
CHOST="i486-pc-linux-gnu"
CFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i486 -O3 -pipe -fomit-frame-pointer"
Pentium 1 (Intel)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium -O3 -pipe -fomit-frame-pointer"
Pentium MMX (Intel)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=pentium-mmx -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium-mmx -O3 -pipe -fomit-frame-pointer"
Pentium PRO (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentiumpro -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentiumpro -O3 -pipe -fomit-frame-pointer"
Pentium II (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
Celeron (Mendocino), aka Celeron1 (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium2 -O3 -pipe -fomit-frame-pointer"
Pentium III (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
Celeron (Coppermine) aka Celeron2 (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium3 -O3 -pipe -fomit-frame-pointer"
Celeron (Willamette?) (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
Pentium 4 (Intel)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer"
Eden C3/Ezra (Via)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=i586 -m3dnow -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=i586 -m3dnow -O3 -pipe -fomit-frame-pointer"
quote : the ezra doesn't have any special instructions that you could optimize for, just consider is a K6-3...basically
a p2 with 3dnow
K6 (AMD)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6 -O3 -pipe -fomit-frame-pointer"
K6-2 (AMD)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=k6-2 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6-2 -O3 -pipe -fomit-frame-pointer"
K6-3 (AMD)
CHOST="i586-pc-linux-gnu"
CFLAGS="-march=k6-3 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=k6-3 -O3 -pipe -fomit-frame-pointer"
Athlon (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon -O3 -pipe -fomit-frame-pointer"
Athlon-tbird, aka K7 (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon-tbird -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-tbird -O3 -pipe -fomit-frame-pointer"
Athlon-tbird XP (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
Athlon 4(AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon-4 -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-4 -O3 -pipe -fomit-frame-pointer"
Athlon XP (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-xp -O3 -pipe -fomit-frame-pointer"
Athlon MP (AMD)
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=athlon-mp -O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=athlon-mp -O3 -pipe -fomit-frame-pointer"
603 (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
603e (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
604 (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
604e (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
750 aka as G3 (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-mcpu=750 -O3 -pipe -fomit-frame-pointer
-fsigned-char"
CXXFLAGS="-mcpu=750 -O3 -pipe -fomit-frame-pointer
-fsigned-char"
Note: do not use -march=
7400, aka G4 (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-mcpu=7400 -O3 -pipe -fomit-frame-pointer
-fsigned-char -maltivec"
CXXFLAGS="-mcpu=7400 -O3 -pipe -fomit-frame-pointer
-fsigned-char -maltivec"
Note: do not use -march=
7450, aka G4 second generation (PowerPC)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-mcpu=7450 -O3 -pipe -fomit-frame-pointer
-fsigned-char -maltivec"
CXXFLAGS="-mcpu=7450 -O3 -pipe -fomit-frame-pointer
-fsigned-char -maltivec"
Note: do not use -march=
PowerPC (If you don't know which one)
CHOST="powerpc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer -fsigned-char"
Sparc
CHOST="sparc-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
Sparc 64
CHOST="sparc64-unknown-linux-gnu"
CFLAGS="-O3 -pipe -fomit-frame-pointer"
CXXFLAGS="-O3 -pipe -fomit-frame-pointer"
--------------------------------------------------------------------
Today I sat near her as she played the
clavichord, all sorts of tunes and with so
much expression. So much! So much!
What could I do?
1. “/etc/profile”文件
2. “bdflush”参数
3. “ip_local_port_range”参数
4. “/etc/nsswitch.conf”文件
5. “/proc”文件系统
6. “ulimit”参数
概述
优化网络性能在很大程度上与网络上使用的软硬件相关。如何优化网络是很难用一本书说得清楚的。在网络真正运行起来之前是很难知道网络的瓶颈所在。性能优化并不是很简单和直观的,必须当作一个很复杂的任务。而且,不仅受到很多约束还需要很高的精确度。除非进行专门的测试以诊断系统中的瓶颈,否则对一些现象很难做出解释。有时,性能优化会变成一项让人十分失望并且乏味的工作,尤其是在经过大量的分析之后所得到的结果仍然不可确定的时候。但是,对系统性能的优化是一项很有回报的工作,并且会给整个系统带来长期的益处。
1. “/etc/profile”文件
“etc/profile”文件含有系统大量的环境和启动程序的配置信息。你在该文件中进行的配置,可以通过申请全局环境变量来实现。因此,在该文件中设置优化标志,是一种明智的选择。要想使x86程序获得最佳性能,可以在编译时,使用最佳的优化选项-O9 。许多程序的“Makefile”文件中已经含有-O2选项,而-O9使编译器采用最高级别的优化。尽管它将增加最终程序的大小,但这样可以获得更高的运行速度。编译时,使用“-fomit-frame-pointer”选项,程序运行时,访问变量时将使用堆栈。但是,使用这一选项,生产的代码将无法调试。使用“-mcpu=cpu_type”和“-march=cpu_type”选项,Gcc将针对这种型号CPU进行专门的优化,但生成的代码只能在所指定的CPU或更高系列的CPU上运行。
对于CPU i686或PentiumPro、Pentium II、Pentium III
在“/etc/profile”文件中 , 加入一行:
CFLAGS=’-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-
frame-pointer -fno-exceptions’
对于CPU i586或Pentium
在“etc/profile”文件中, 加入一行:
CFLAGS=’-O3 -march=pentium -mcpu=pentium -ffast-math -funroll-loops -fomit-frame-pointer -fforce-
mem -fforce-addr -malign-double -fno-exceptions’
对于CPU i486
在“etc/profile”文件中, 加入一行:
CFLAGS=’-O3 -funroll-all-loops -malign-double -mcpu=i486 -march=i486 -fomit-frame-pointer -fno-exceptions’
在进行完以上设置之后,紧接者着把“CFLAGS LANG LESSCHARSET”加入到“etc/profile”文件中的“export”行中:
export PATH PS1 HOSTNAME HISTSIZE HISTFILESIZE USER LOGNAME MAIL INPUTRC CFLAGS LANG LESSCHARSET
然后,重新登录,这时,环境变量CFLAGS已经被赋值,编译器和其它配置工具可以使用它。对Pentium(Pro/II/III)的优化必须使用egcs或pgcc编译器。Linux的缺省安装中,已经装上了egcs,所以无需担心。
基准测试结果(按体系结构分类):
由于CPU的体系结构和使用的gcc/egcs的版本不同,优化选项也会不同。下面的图表可以帮助你根据自己的CPU和编译器,选择最佳的编译选项。
Redhat 6.1中安装的编译器的版本是egcs 2.91.66,但是,即使你安装的就是Redhat 6.1,在选择编译选项之前也务必检查一下编译器的版本.
为了确认编译器的版本,使用如下命令:
[root@deep]# egcs --version。
注意:所有的测试结果可以从GCC的主页:
上检索到。
现举例说明:
对于CPU pentium II/III(i686),安装了egcs-2.91.66,最佳的编译选项是:
CFLAGS=’-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-frame-pointer -fno-exceptions’
对于CPU pentium (i586),安装了egcs-2.91.66, 最佳的编译选项是:
CFLAGS=’-O3 -march=pentium -mcpu=pentium -ffast-math -funroll-loops -fomit-frame-pointer -fforce-mem -fforce-addr -malign-double -fno-exceptions’
对于 CPU i486,安装了egcs-2.91.66,最佳的编译选项是:
CFLAGS=’-O3 -funroll-all-loops -malign-double -mcpu=i486 -march=i486 -fomit-frame-pointer -fno-exceptions’
-funroll-loops选项
对“loop unrolling”进行优化,只对在编译或运行时循环次数能确定的循环语句有效。
-funroll-all-loops
对“loop unrolling”进行优化,对所有的循环语句有效,担通常使程序运行变慢。
-ffast-math
该选项使GCC可以不遵从ANSI或IEEE的规则,以获得运行更快的优化代码。例如:它允许编译器假设sqrt()函数的输入参数非负以及所有的浮点数的值都是NaNs。
-malign-double
GCC把 double, long double, and long long类型变量定界在双字还是单字边界上,由该选项控制。double类型变量定界于双字边界时,产生的代码在Pentium机器上可以运行得更快一些,但是会占用更多的内存。
-mcpu=cpu_type
设定在生成指令时缺省的机器和CPU类型,设定好某一特定的CPU类型后,编译器将针对这种芯片产生相应的指令,如果不使用“-march=cpu_type”选项,编译器不会产生任何不能在i386上运行的代码。“i586”等价于“pentium”,“i686”等价于“pentiumpro”,“k6”指明是使用AMD的芯片而非Intel系列。
-march=cpu_type
为指定类型的机器和CPU产生指令。这里的CPU类型与“-mcpu”中列出的相同。而且,使用本选项已经隐含了“-mcpu=cpu_type”选项。
-fforce-mem
对于涉及内存操作的运算,强制把操作数拷贝到寄存器中。这是通过把所有的内存引用转换成潜在的普通子表达式,以获得优化代码。如果,这些内存引用不是普通子表达式,可以通过指令的组合,消除单独的寄存器装载。
-fforce-addr
运算前把内存地址常数拷贝到寄存器中。所产生的优化代码与选项“-fforce-mem”类似。
-fomit-frame-pointer
对于不必要的框架指针(frame pointer),不在寄存器中保存。这就避免了相应的用于保存、设置和恢复框架指针所需的指令;这样,许多函数中可以使用额外的寄存器。但是,这一选项使得在大多数机器上无法进行调试。
注意:本书将要讨论的所有优化,缺省都是针对Pentium II/III 系列CPU。因此,如有必要,对于某些专门的CPU需要调整编译参数。
2. “bdflush”参数
下文讨论目录“/proc/sys/vm”下的系统控制文件,且只在Linux内核版本2.2下有效。控制该目录下的文件,可以调整Linux内核子系统--虚拟内存(VM)的行为,其中bdflush文件对于硬盘使用有一定影响。该文件控制了bdflush内核守护进程的行为。我们通常使用以下命令来提高文件系统的性能:
echo "100 1200 128 512 15 5000 500 1884 2">/proc/sys/vm/bdflush
修改某些值,可以使系统响应更快,例如:可以使系统在写入硬盘之前等待更长时间,从而避免了一些硬盘访问的冲突。
把该命令加入文件“etc/rc.d/rc.local”之中,每次重新启动机器时,就不必再次手工敲入这条命令了。
如果需要进一步理解如何改进有关虚拟内存、硬盘缓冲和交换空间(swap)的内核参数,可以参照“/usr/src/linux/Documentation/sysctl/vm.txt”。
3. “ip_local_port_range”参数
下文讨论目录“/proc/sys/net/ipv4/ip_local_port_range”下的系统控制文件,且只在Linux内核版本2.2下有效。
“ip_local_port_range”文件中有两个参数分别定义了用作TCP和UDP本地端口的端口范围。第一个参数是第一个端口号。第二个参数是最后一个本地端口号。对于使用率很高的系统,可以修改为:32768到61000。
echo *32768 61000* > /proc/sys/net/ipv4/ip_local_port_range
把该命令加入文件“/etc/rc.d/rc.local”之中,每次重新启动机器时,就不必再次手工敲入这条命令了。
4. “/etc/nsswitch.conf”文件
“etc/nsswitch.conf”文件定义了系统使用哪些服务来解析主机名、获得口令文件和组文件(group file)。我们的系统中由于没有使用NIS服务,因此口令文件和组文件我们没有使用。这里,我们只讨论该文件中的hosts这一行。
编辑“nsswitch.conf”文件(vi /etc/nsswitch.conf),把host一行改为:
"hosts: dns files"
含义:当请求解析地址时,首先访问DNS服务器,如果DNS服务器没有响应,则使用“/etc/hosts”文件。
我建议把该文件中每一行中的NIS都删掉。当然,如果你一定要使用NIS,就不能删掉NIS。最后,这个文件会是这样:
passwd: files
shadow: files
group: files
hosts: dns files
bootparams: files
ethers: files
netmasks: files
networks: files
protocols: files
rpc: files
services: files
automount: files
aliases: files
5. “/proc”文件系统
下文讨论目录“proc/sys/fs”下的系统控制文件,且只在Linux内核版本2.2下有效。该目录下的文件可以用来调整和监测Linux内核的一些行为。对这些文件的误操作可能搅乱系统,因此在实际调整系统之前,最好把文档和源代码都读一下。
适当的增加“/proc/sys/fs/file-max”的值:每4M内存对应256,例如:内存为128M的机器,该值可以设为8192(128/4=32 32*256=8192)。同理,可以增加“/proc/sys/fs/inode-max”的值,使其值为打开文件数目的3到4倍(8192*4=32768)。这是因为:i节点的数目至少等于打开的文件数,一般而言,对于大文件,i节点数远大于打开的文件数目。
用于改变/proc目录及其子目录下的任意参数的常用命令是(必须以root登录): echo “新的参数值”> “/proc/所需更改的文件”,对于上面所涉及的修改,其命令为:
echo "8192" >/proc/sys/fs/file-max
echo "32768" >/proc/sys/fs/inode-max
上文所讨论的方法修改了内核源代码的常数。但是,在新的内核源代码树中并不能起作用,因此还不能算是最好的方法。最好的一种方法是把上述命令加入文件“etc/rc.d/rc.local”之中。在该文件的最后加入以下两行(假设系统有128M内存):
echo "8192" >/proc/sys/fs/file-max
echo "32768" >/proc/sys/fs/inode-max
其中的数值因系统不同,差异很大,应该根据各自系统,按照上述的公式计算。一台文件服务器或WEB服务器需要打开的文件数目就很大,而用于数值的服务器该数值就较小。
对于内存非常多的系统,特别是512M或更多内存的系统,打开的文件数和i节点数最好不要超过50,000和150,000。
“file-max”参数是指Linux内核可以分配的文件句柄的最大数目。当系统经常报错:文件句柄不够时,就需要适当增大该参数的值。系统缺省值为:4096。
“inode-max”参数是指系统i节点句柄的最大数目。其值应该是file-max值的3到4倍。因为标准输入输出文件和网络套接字都要使用i节点来进行处理。如果系统经常性的出现i节点被耗尽的情况,就需要增大其值。
概述
1. “/etc/profile”文件
2. “bdflush”参数
3. “ip_local_port_range”参数
4. “/etc/nsswitch.conf”文件
5. “/proc”文件系统
6. “ulimit”参数
概述
优化网络性能在很大程度上与网络上使用的软硬件相关。如何优化网络是很难用一本书说得清楚的。在网络真正运行起来之前是很难知道网络的瓶颈所在。性能优化并不是很简单和直观的,必须当作一个很复杂的任务。而且,不仅受到很多约束还需要很高的精确度。除非进行专门的测试以诊断系统中的瓶颈,否则对一些现象很难做出解释。有时,性能优化会变成一项让人十分失望并且乏味的工作,尤其是在经过大量的分析之后所得到的结果仍然不可确定的时候。但是,对系统性能的优化是一项很有回报的工作,并且会给整个系统带来长期的益处。
1. “/etc/profile”文件
“etc/profile”文件含有系统大量的环境和启动程序的配置信息。你在该文件中进行的配置,可以通过申请全局环境变量来实现。因此,在该文件中设置优化标志,是一种明智的选择。要想使x86程序获得最佳性能,可以在编译时,使用最佳的优化选项-O9 。许多程序的“Makefile”文件中已经含有-O2选项,而-O9使编译器采用最高级别的优化。尽管它将增加最终程序的大小,但这样可以获得更高的运行速度。编译时,使用“-fomit-frame-pointer”选项,程序运行时,访问变量时将使用堆栈。但是,使用这一选项,生产的代码将无法调试。使用“-mcpu=cpu_type”和“-march=cpu_type”选项,Gcc将针对这种型号CPU进行专门的优化,但生成的代码只能在所指定的CPU或更高系列的CPU上运行。
对于CPU i686或PentiumPro、Pentium II、Pentium III
在“/etc/profile”文件中 , 加入一行:
CFLAGS=’-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-
frame-pointer -fno-exceptions’
对于CPU i586或Pentium
在“etc/profile”文件中, 加入一行:
CFLAGS=’-O3 -march=pentium -mcpu=pentium -ffast-math -funroll-loops -fomit-frame-pointer -fforce-
mem -fforce-addr -malign-double -fno-exceptions’
对于CPU i486
在“etc/profile”文件中, 加入一行:
CFLAGS=’-O3 -funroll-all-loops -malign-double -mcpu=i486 -march=i486 -fomit-frame-pointer -fno-exceptions’
在进行完以上设置之后,紧接者着把“CFLAGS LANG LESSCHARSET”加入到“etc/profile”文件中的“export”行中:
export PATH PS1 HOSTNAME HISTSIZE HISTFILESIZE USER LOGNAME MAIL INPUTRC CFLAGS LANG LESSCHARSET
然后,重新登录,这时,环境变量CFLAGS已经被赋值,编译器和其它配置工具可以使用它。对Pentium(Pro/II/III)的优化必须使用egcs或pgcc编译器。Linux的缺省安装中,已经装上了egcs,所以无需担心。
基准测试结果(按体系结构分类):
由于CPU的体系结构和使用的gcc/egcs的版本不同,优化选项也会不同。下面的图表可以帮助你根据自己的CPU和编译器,选择最佳的编译选项。
Redhat 6.1中安装的编译器的版本是egcs 2.91.66,但是,即使你安装的就是Redhat 6.1,在选择编译选项之前也务必检查一下编译器的版本.
为了确认编译器的版本,使用如下命令:
[root@deep]# egcs --version。
注意:所有的测试结果可以从GCC的主页:
上检索到。
现举例说明:
对于CPU pentium II/III(i686),安装了egcs-2.91.66,最佳的编译选项是:
CFLAGS=’-O9 -funroll-loops -ffast-math -malign-double -mcpu=pentiumpro -march=pentiumpro -fomit-frame-pointer -fno-exceptions’
对于CPU pentium (i586),安装了egcs-2.91.66, 最佳的编译选项是:
CFLAGS=’-O3 -march=pentium -mcpu=pentium -ffast-math -funroll-loops -fomit-frame-pointer -fforce-mem -fforce-addr -malign-double -fno-exceptions’
对于 CPU i486,安装了egcs-2.91.66,最佳的编译选项是:
CFLAGS=’-O3 -funroll-all-loops -malign-double -mcpu=i486 -march=i486 -fomit-frame-pointer -fno-exceptions’
-funroll-loops选项
对“loop unrolling”进行优化,只对在编译或运行时循环次数能确定的循环语句有效。
-funroll-all-loops
对“loop unrolling”进行优化,对所有的循环语句有效,担通常使程序运行变慢。
-ffast-math
该选项使GCC可以不遵从ANSI或IEEE的规则,以获得运行更快的优化代码。例如:它允许编译器假设sqrt()函数的输入参数非负以及所有的浮点数的值都是NaNs。
-malign-double
GCC把 double, long double, and long long类型变量定界在双字还是单字边界上,由该选项控制。double类型变量定界于双字边界时,产生的代码在Pentium机器上可以运行得更快一些,但是会占用更多的内存。
-mcpu=cpu_type
设定在生成指令时缺省的机器和CPU类型,设定好某一特定的CPU类型后,编译器将针对这种芯片产生相应的指令,如果不使用“-march=cpu_type”选项,编译器不会产生任何不能在i386上运行的代码。“i586”等价于“pentium”,“i686”等价于“pentiumpro”,“k6”指明是使用AMD的芯片而非Intel系列。
-march=cpu_type
为指定类型的机器和CPU产生指令。这里的CPU类型与“-mcpu”中列出的相同。而且,使用本选项已经隐含了“-mcpu=cpu_type”选项。
-fforce-mem
对于涉及内存操作的运算,强制把操作数拷贝到寄存器中。这是通过把所有的内存引用转换成潜在的普通子表达式,以获得优化代码。如果,这些内存引用不是普通子表达式,可以通过指令的组合,消除单独的寄存器装载。
-fforce-addr
运算前把内存地址常数拷贝到寄存器中。所产生的优化代码与选项“-fforce-mem”类似。
-fomit-frame-pointer
对于不必要的框架指针(frame pointer),不在寄存器中保存。这就避免了相应的用于保存、设置和恢复框架指针所需的指令;这样,许多函数中可以使用额外的寄存器。但是,这一选项使得在大多数机器上无法进行调试。
注意:本书将要讨论的所有优化,缺省都是针对Pentium II/III 系列CPU。因此,如有必要,对于某些专门的CPU需要调整编译参数。
2. “bdflush”参数
下文讨论目录“/proc/sys/vm”下的系统控制文件,且只在Linux内核版本2.2下有效。控制该目录下的文件,可以调整Linux内核子系统--虚拟内存(VM)的行为,其中bdflush文件对于硬盘使用有一定影响。该文件控制了bdflush内核守护进程的行为。我们通常使用以下命令来提高文件系统的性能:
echo "100 1200 128 512 15 5000 500 1884 2">/proc/sys/vm/bdflush
修改某些值,可以使系统响应更快,例如:可以使系统在写入硬盘之前等待更长时间,从而避免了一些硬盘访问的冲突。
把该命令加入文件“etc/rc.d/rc.local”之中,每次重新启动机器时,就不必再次手工敲入这条命令了。
如果需要进一步理解如何改进有关虚拟内存、硬盘缓冲和交换空间(swap)的内核参数,可以参照“/usr/src/linux/Documentation/sysctl/vm.txt”。
3. “ip_local_port_range”参数
下文讨论目录“/proc/sys/net/ipv4/ip_local_port_range”下的系统控制文件,且只在Linux内核版本2.2下有效。
“ip_local_port_range”文件中有两个参数分别定义了用作TCP和UDP本地端口的端口范围。第一个参数是第一个端口号。第二个参数是最后一个本地端口号。对于使用率很高的系统,可以修改为:32768到61000。
echo *32768 61000* > /proc/sys/net/ipv4/ip_local_port_range
把该命令加入文件“/etc/rc.d/rc.local”之中,每次重新启动机器时,就不必再次手工敲入这条命令了。
4. “/etc/nsswitch.conf”文件
“etc/nsswitch.conf”文件定义了系统使用哪些服务来解析主机名、获得口令文件和组文件(group file)。我们的系统中由于没有使用NIS服务,因此口令文件和组文件我们没有使用。这里,我们只讨论该文件中的hosts这一行。
编辑“nsswitch.conf”文件(vi /etc/nsswitch.conf),把host一行改为:
"hosts: dns files"
含义:当请求解析地址时,首先访问DNS服务器,如果DNS服务器没有响应,则使用“/etc/hosts”文件。
我建议把该文件中每一行中的NIS都删掉。当然,如果你一定要使用NIS,就不能删掉NIS。最后,这个文件会是这样:
passwd: files
shadow: files
group: files
hosts: dns files
bootparams: files
ethers: files
netmasks: files
networks: files
protocols: files
rpc: files
services: files
automount: files
aliases: files
5. “/proc”文件系统
下文讨论目录“proc/sys/fs”下的系统控制文件,且只在Linux内核版本2.2下有效。该目录下的文件可以用来调整和监测Linux内核的一些行为。对这些文件的误操作可能搅乱系统,因此在实际调整系统之前,最好把文档和源代码都读一下。
适当的增加“/proc/sys/fs/file-max”的值:每4M内存对应256,例如:内存为128M的机器,该值可以设为8192(128/4=32 32*256=8192)。同理,可以增加“/proc/sys/fs/inode-max”的值,使其值为打开文件数目的3到4倍(8192*4=32768)。这是因为:i节点的数目至少等于打开的文件数,一般而言,对于大文件,i节点数远大于打开的文件数目。
用于改变/proc目录及其子目录下的任意参数的常用命令是(必须以root登录): echo “新的参数值”> “/proc/所需更改的文件”,对于上面所涉及的修改,其命令为:
echo "8192" >/proc/sys/fs/file-max
echo "32768" >/proc/sys/fs/inode-max
上文所讨论的方法修改了内核源代码的常数。但是,在新的内核源代码树中并不能起作用,因此还不能算是最好的方法。最好的一种方法是把上述命令加入文件“etc/rc.d/rc.local”之中。在该文件的最后加入以下两行(假设系统有128M内存):
echo "8192" >/proc/sys/fs/file-max
echo "32768" >/proc/sys/fs/inode-max
其中的数值因系统不同,差异很大,应该根据各自系统,按照上述的公式计算。一台文件服务器或WEB服务器需要打开的文件数目就很大,而用于数值的服务器该数值就较小。
对于内存非常多的系统,特别是512M或更多内存的系统,打开的文件数和i节点数最好不要超过50,000和150,000。
“file-max”参数是指Linux内核可以分配的文件句柄的最大数目。当系统经常报错:文件句柄不够时,就需要适当增大该参数的值。系统缺省值为:4096。
“inode-max”参数是指系统i节点句柄的最大数目。其值应该是file-max值的3到4倍。因为标准输入输出文件和网络套接字都要使用i节点来进行处理。如果系统经常性的出现i节点被耗尽的情况,就需要增大其值。
6. “ulimit”参数
Linux本身对每个用户拥有的最大进程数有限制。可以在用户根目录下的“.bashrc”文件或者实际使用与“.bashrc”功能相当的shell的脚本中加入这种限制。编辑“.bashrc”文件(例如:vi /root/.bashrc)并加入下面一行:
ulimit -u unlimited
然后退出,重新登录。为了验证,可以以root身份登录,然后键入: “ulimit ?a”,在最大用户进程数一项中应该显示“unlimited”,例如:
[root@deep]# ulimit -a
core file size (blocks) 1000000
data seg size (kbytes) unlimited
file size (blocks) unlimited
max memory size (kbytes) unlimited
stack size (kbytes) 8192
cpu time (seconds) unlimited
max user processes unlimited * this line.
pipe size (512 bytes) 8
open files 1024
virtual memory (kbytes) 2105343
注意:你可能更倾向于在命令行键入“unlimit ?u”而不是把它加入到文件“/root/.bashrc”中。但为保险起见,建议还是把它加入文件“/root/.bashrc”中。
--------------------------------------------------------------------------------
__________________
Today I sat near her as she played the
clavichord, all sorts of tunes and with so
much expression. So much! So much!
What could I do?
向版主报告此贴 | IP地址: 已记录
11-02-2004 21:52
neplusultra
★
注册日期: Sep 2004
来 自:
发贴数量: 178
[系统优化二
7. 增加系统打开的文件数目
8. 文件“atime”属性
9. 文件的“noatime”属性
10. 特定的TCP/IP栈
11. 交换分区
12. 调整IDE硬盘性能
PHP源码:
--------------------------------------------------------------------------------
7. 增加系统打开的文件数目
增加当前进程打开文件的数目。RedHat 6.0(内核2.2.5)中,用这种方法进程可以至少打开31000个文件描述符;内核版本为2.2.12中,可以至少打开90000个文件描述符(在适当的限制下)。它的上限仅受限于可用内存。
编辑“.bashrc”文件(例如:vi /root/.bashrc)并加入下面一行:
ulimit -n 90000
然后退出,重新登录。为了验证,可以以root身份登录,然后键入“ulimit ?a”,在打开文件数一项中应该显示“90000”,例如:
[root@deep]# ulimit -a
core file size (blocks) 1000000
data seg size (kbytes) unlimited
file size (blocks) unlimited
max memory size (kbytes) unlimited
stack size (kbytes) 8192
cpu time (seconds) unlimited
max user processes unlimited
pipe size (512 bytes) 8
open files 90000 * this line.
virtual memory (kbytes) 2105343
注意:在早于2.2版内核的系统中,即使进行了上述修改,每个进程所能打开的文件数目仍然限制为1024。
8. 文件“atime”属性
Linux除了记录文件的创建和修改时间外,还记录文件最近的访问时间。该信息作用不大,但为保留它,系统需要消耗相应的资源。ext2文件系统允许超级用户对单个文件进行标记,以忽略对这条信息的记录。
这种优化调整,对于文件查找操作,系统性能提高显著,另外,对于需要经常访问的文件(如:/var/spool/news)也是很有用的。设置该属性的命令为:
[root@deep]# chattr +A filename
若需要对某个目录下的所有文件进行这种设置,可以使用:
[root@deep /root]# chattr -R +A /var/spool/
[root@deep /root]# chattr -R +A /cache/
[root@deep /root]# chattr -R +A /home/httpd/ona/
9. 文件的“noatime”属性
Linux在mount文件系统时,可以使用“noatime”选项。并可以在文件“/etc/fstab”的mount选项区域中加入。当含有该选项的
文件系统被挂入(mount)系统时,对该文件系统中的文件的读访问,不再更新文件的atime信息。一般情况下,atime信息没有用,所以不更新该域并无大碍。这一选项的重要性在于:当只对文件进行读操作时,不再需要向文件系统中该文件的相应区域写入信息。因为写入操作的开销某种意义下是昂贵的,因此该选项可以获得明显的性能的改善。该选项对于文件的wtime属性没有影响,每次文件写操作时,都会更新文件的wtime信息。
编辑“fstab”文件(vi /etc/fstab)并且加入如下一行(举例说明):
E.I: /dev/sda7 /chroot ext2 defaults,noatime 1 2
重新启动系统, 然后用以下命令测试结果:
[ ]# reboot
[ ]# cat /proc/mounts
10. 特定的TCP/IP栈
RedHat Linux , 一般情况下,并不优化 TCP/IP 窗口大小。这能使系统性能的差别很大。如需更多的信息,参阅:RFC 1106 - High Latency WAN links - Section 4.1 and RFC 793 - Transmission Control Protocol。
编辑文件“/etc/sysconfig/network-scripts/ifup”,在110、112、117、125和134行,有:
110: "route add -net ${NETWORK} netmask ${NETMASK} ${DEVICE}"
112: "route add -host ${IPADDR} ${DEVICE}"
117: "route add default gw ${GATEWAY} metric 1 ${DEVICE}"
125: "route add default gw ${GATEWAY} ${DEVICE}"
134: "route add default gw $gw ${DEVICE}"
修改为:
110: "route add -net ${NETWORK} netmask ${NETMASK} window 8192 ${DEVICE}"
112: "route add -host ${IPADDR} window 8192 ${DEVICE}"
117: "route add default gw ${GATEWAY} window 8192 metric 1 ${DEVICE}"
125: "route add default gw ${GATEWAY} window 8192 ${DEVICE}"
134: "route add default gw $gw window 8192 ${DEVICE}"
11. 交换分区
尽量把交换分区放在硬盘的开始区域。硬盘的开始区域物理上位于硬盘柱面的外环部分,因此硬盘的每转能在这一部分读写更多的信息。我曾经见过,在运行命令“hdparm ?t”时,把交换分区放在硬盘的结尾部分市,系统的读写速度比放在硬盘的开始部分低3MB/s。
12. 调整IDE硬盘性能
在有大量的磁盘 I/O 操作时,设置IDE硬盘使用 DMA 、32 位的传送和多重的扇区模式(Multiple sector mode),可以大幅提高系统性能。除非显式的告诉内核使用这些模式,内核缺省是使用保守设置的。
使用如下命令,以使PCI总线允许32位I/O操作:
[root@deep]# /sbin/hdparm -c 1 /dev/hda (或hdb, hdc 等等)
hdparm(8) 的帮助信息(manpage)中说明了:对于某些芯片需要使用选项“-c 3”。所有的(E)IDE硬盘与接口卡相连的扁平电缆中只用16-bit的连接。
使用如下命令,以允许DMA方式:
[root@deep]# /sbin/hdparm -d 1 /dev/hda (或hdb, hdc 等等)
这取决于编译内核时选择的主板芯片组。
使用如下命令,以允许多字的DMA模式2传送:
[root@deep]# /sbin/hdparm -d 1 -X34 /dev/hda (或hdb, hdc 等等)
这为较新的(E)IDE/ATA2硬盘设置IDE的传送模式。(参阅硬盘手册,以核实你的硬盘是否支持这种模式)
使用如下命令,以允许UltraDMA 模式2:
[root@deep]# /sbin/hdparm -d 1 -X66 /dev/hda (或hdb, hdc 等等)
使用该命令之前,事先应该有支持UltraDMA的芯片组,并参看hdparm的帮助信息。使用该命令时,务必小心。
使用如下命令,以允许多扇区I/O模式:
[root@deep]# /sbin/hdparm -m XX /dev/hda (或hdb, hdc 等等)
其中,参数XX是指使用硬盘支持的最大设置。可以使用“-i”选项来自动查找所装硬盘支持的最大设置。可以在输出中查看MaxMultSect的值。例如:
[root@deep]# /sbin/hdparm -i /dev/hda (或hdb, hdc 等等)
/dev/hda:
Model=Maxtor 7540 AV, FwRev=GA7X4647, SerialNo=L1007YZS
Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>5Mbs FmtGapReq }
RawCHS=1046/16/63, TrkSize=0, SectSize=0, ECCbytes=11
BuffType=3(DualPortCache), BuffSize=32kB, MaxMultSect=8, MultSect=8
DblWordIO=yes, maxPIO=2(fast), DMA=yes, maxDMA=1(medium)
CurCHS=523/32/63, CurSects=379584528, LBA=yes, LBA=yes, LBAsects=1054368
tDMA={min:150,rec:150}, DMA modes: sword0 sword1 *sword2 *mword0
IORDY=on/off, tPIO={min:240,w/IORDY:180}, PIO modes: mode3
目前的大多数的硬盘驱动器都支持多扇区模式(Multiple sector mode 或aka IDE Block Mode),它允许一次中断中传送多个扇区而不是一次中断传送一个扇区。具有这种特性的硬盘驱动器,能使操作系统在硬盘I/O时的负载下降30-50%。在许多系统中,它能提高数据的吞吐率5-50%。
可以用hdparm的测试模式,来测试所作修改的结果:
[root@deep]# /sbin/hdparm -t /dev/hda (或hdb, hdc 等等)
进行了以上修改后,不要忘记把它们加入到文件“/etc/rc.d/rc.local”中,以便每次重启系统时,能够自动运行。