从cupinfo的信息可以看出,支持sse/sse2/mmx这些GCC的flag,查看gcc的文档可以看到全部的优化选项:[点我查看]。
经过尝试,得到了如下编译参数,经过两周的压力测试,编译MySQL 5.1.46sp1企业版,比Percona 5.1.47 Server性能高出15%,目前也非常稳定的运行在开发测试库上。GCC版本为4.1.3,系统为RHEL 5.4 x.
CXX=gcc \
CHOST=”x86_-pc-linux-gnu” \
CFLAGS=” -O3 \
-fomit-frame-pointer \
-pipe \
-march=nocona \
-mfpmath=sse \
-m128bit-long-double \
-mmmx \
-msse \
-msse2 \
-maccumulate-outgoing-args \
-m \
-ftree-loop-linear \
-fprefetch-loop-arrays \
-freg-struct-return \
-fgcse-sm \
-fgcse-las \
-frename-registers \
-fforce-addr \
-fivopts \
-ftree-vectorize \
-ftracer \
-frename-registers \
-minline-all-stringops \
-fbranch-target-load-optimize2″ \
CXXFLAGS=”${CFLAGS}” \
./configure –prefix=/usr/soft/install/mysql-ent-official-5.1.56 \
–with-server-suffix=custom-mysql \
–with-mysqld-user=mysql \
–with-plugins=partition,blackhole,csv,heap,innobase,myisam,myisammrg \
–with-charset=utf8 \
–with-collation=utf8_general_ci \
–with-extra-charsets=gbk,gb2312,utf8,ascii \
–with-big-tables \
–with-fast-mutexes \
–with-zlib-dir=bundled \
–enable-assembler \
–enable-profiling \
–enable-local-infile \
–enable-thread-safe-client \
–with-readline \
–with-pthread \
–with-embedded-server \
–with-client-ldflags=-all-static \
–with-mysqld-ldflags=-all-static \
–without-query-cache \
–without-geometry \
–without-debug \
–without-ndb-debug
GCC参数的含义为:
-fomit-frame-pointer
对于不需要栈指针的函数就不在寄存器中保存指针,因此可以忽略存储和检索地址的代码,同时对许多函数提供一个额外的寄存器。所有”-O”级别都打开它,但仅在调试器可以不依靠栈指针运行时才有效。在AMD平台上此选项默认打开,但是在x86平台上则默认关闭。建议显式的设置它。
-pipe
在编译过程的不同阶段之间使用管道而非临时文件进行通信,可以加快编译速度。建议使用。
-march=nocona
Xoen 55xx处理器在GCC 4.1.3
-mfpmath=sse
启用cpu支持”sse”标量浮点指令。
m128bit-long-double
指定long double为128位,pentium以上的cpu更喜欢这种标准,并且符合x86-的ABI标准,但是却不附合i386的ABI标准。
-mmmx -msse -msse2
使用相应的扩展指令集以及内置函数
-maccumulate-outgoing-args
指定在函数引导段中计算输出参数所需最大空间,这在大部分现代cpu中是较快的方法;缺点是会明显增加二进制文件尺寸。
-m
生成专门运行于位环境的代码,不能运行于32位环境,仅用于x86_[含EMT]环境。
-ftree-loop-linear
在trees上进行线型循环转换。它能够改进缓冲性能并且允许进行更进一步的循环优化。
-fprefetch-loop-arrays
生成数组预读取指令,对于使用巨大数组的程序可以加快代码执行速度,适合数据库相关的大型软件等。具体效果如何取决于代码。
-freg-struct-return
如果struct和union足够小就通过寄存器返回,这将提高较小结构的效率。如果不够小,无法容纳在一个寄存器中,将使用内存返回。建议仅在完全使用GCC编译的系统上才使用。
-fgcse-sm
在全局公共子表达式消除之后运行存储移动,以试图将存储移出循环。
-fgcse-las
在全局公共子表达式消除之后消除多余的在存储到同一存储区域之后的加载操作。
-frename-registers \
-fforce-addr
必须将地址复制到寄存器中才能对他们进行运算。由于所需地址通常在前面已经加载到寄存器中了,所以这个选项可以改进代码。
-fivopts
在trees上执行归纳变量优化。
-ftree-vectorize
在trees上执行循环向量化。
-ftracer
执行尾部复制以扩大超级块的尺寸,它简化了函数控制流,从而允许其它的优化措施做的更好。
-frename-registers
试图驱除代码中的假依赖关系,这个选项对具有大量寄存器的机器很有效。
-minline-all-stringops
默认时GCC只将确定目的地会被对齐在至少4字节边界的字符串操作内联进程序代码。该选项启用更多的内联并且增加二进制文件的体积,但是可以提升依赖于高速 memcpy, strlen, memset 操作的程序的性能。数据库系统使用这个参数可以显著提高内存操作性能。
-fbranch-target-load-optimize2
在执行序启动以及结尾之前执行分支目标缓存器加载最佳化。
第二部分,使用TC-Malloc内存管理:
Linux下的malloc函数性能问题,想必大部分在Linux下写C的人都深有感受,纷纷利用内存池来改进内存分配效率。
Google开源的tcmalloc则改进了malloc的一些效率问题,在大量malloc和free时,操作系统的内存曲线明显比Linux下malloc函数要平稳,在大并发情况下,提升程序稳定性和性能。
一般网上都是把tcmalloc动态库加到mysqld_safe中启动,但是我们的MySQL都是静态编译的,这时候动态加载是否生效呢?所以还是静态编译入MySQL好。
编译tcmalloc先要编译libunwind:
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99.tar.gz
tar zxvf libunwind-0.99.tar.gz
CHOST=”x86_-pc-linux-gnu” \
CFLAGS=” -O3 -fPIC \
-fomit-frame-pointer \
-pipe \
-march=nocona \
-mfpmath=sse \
-m128bit-long-double \
-mmmx \
-msse \
-msse2 \
-maccumulate-outgoing-args \
-m \
-ftree-loop-linear \
-fprefetch-loop-arrays \
-freg-struct-return \
-fgcse-sm \
-fgcse-las \
-frename-registers \
-fforce-addr \
-fivopts \
-ftree-vectorize \
-ftracer \
-frename-registers \
-minline-all-stringops \
-fbranch-target-load-optimize2″ \
CXXFLAGS=”${CFLAGS}” \
./configure && make && make install
然后编译tcmalloc:
tar zxvf google-perftools-1.7.tar.gz
CHOST=”x86_-pc-linux-gnu” \
CFLAGS=” -O3 \
-fomit-frame-pointer \
-pipe \
-march=nocona \
-mfpmath=sse \
-m128bit-long-double \
-mmmx \
-msse \
-msse2 \
-maccumulate-outgoing-args \
-m \
-ftree-loop-linear \
-fprefetch-loop-arrays \
-freg-struct-return \
-fgcse-sm \
-fgcse-las \
-frename-registers \
-fforce-addr \
-fivopts \
-ftree-vectorize \
-ftracer \
-frename-registers \
-minline-all-stringops \
-fbranch-target-load-optimize2″ \
CXXFLAGS=”${CFLAGS}” \
./configure –disable-cpu-profiler \
–disable-heap-profiler \
–disable-heap-checker \
–disable-debugalloc \
–enable-minimal \
–enable-frame-pointers && make && make install
记得要把libtammloc加入系统路径,否则编译MySQL时找不到:
echo “/usr/local/lib” > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
最后就是编译MySQL了:
CXX=gcc \
CHOST=”x86_-pc-linux-gnu” \
CFLAGS=” -O3 \
-fomit-frame-pointer \
-pipe \
-march=nocona \
-mfpmath=sse \
-m128bit-long-double \
-mmmx \
-msse \
-msse2 \
-maccumulate-outgoing-args \
-m \
-ftree-loop-linear \
-fprefetch-loop-arrays \
-freg-struct-return \
-fgcse-sm \
-fgcse-las \
-frename-registers \
-fforce-addr \
-fivopts \
-ftree-vectorize \
-ftracer \
-frename-registers \
-minline-all-stringops \
-felide-constructors \
-fno-exceptions \
-fno-rtti \
-fbranch-target-load-optimize2″ \
CXXFLAGS=”${CFLAGS}” \
LDFLAGS=” -lrt -lunwind -ltcmalloc_minimal -lstdc++ ” \
./configure –prefix=/usr/soft/install/mysql-ent-custom-5.1.49sp1 \
–with-server-suffix=-custom-edition \
–with-mysqld-user=mysql \
–with-plugins=partition,blackhole,csv,heap,innobase,myisam,myisammrg \
–with-charset=utf8 \
–with-collation=utf8_general_ci \
–with-extra-charsets=gbk,gb2312,utf8,ascii \
–with-big-tables \
–with-fast-mutexes \
–with-zlib-dir=bundled \
–enable-assembler \
–enable-profiling \
–enable-local-infile \
–enable-thread-safe-client \
–with-readline \
–with-pthread \
–with-embedded-server \
–with-mysqld-ldflags=-all-static \
–without-query-cache \
–without-geometry \
–without-debug \
–without-ndb-debug
make && make install
经过试用,大并发下内存分配和释放曲线都比Linux原生的平稳。
第三部分,尝试ICC:
ICC是Intel自己开发的多平台编译器,经过我的测试ICC在浮点运算,线程库和数学函数上的优势非常明显,原生SSE2指令集支持、Intel自己编写的线程库和数学函数库,性能没得说。
我用同一份运算PI值的代码在ICC和GCC下编译,提升比例达20%,实际在数据库中比较同一条超级复杂的聚合SQL,ICC提升达34%。
下面给出TC-Malloc + ICC + Percona从源码编译的完整方案。
第一步:编译安装libunwind
wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99.tar.gz
tar zxvf libunwind-0.99.tar.gz
CC=icc \
CXX=icpc \
LD=xild \
AR=xiar \
CFLAGS=”-O3 -no-prec-div -ip -fp-model fast=1 -xSSE2 -axSSE2 -fPIC” \
CXXFLAGS=”${CFLAGS}” \
CPPFLAGS=” -I/usr/alibaba/icc/include ” \
./configure && make && make install
第二布:编译安装tcmalloc
wget http://google-perftools.googlecode.com/files/google-perftools-1.7.tar.gz
tar zxvf google-perftools-1.7.tar.gz
CC=icc \
CXX=icpc \
LD=xild \
AR=xiar \
CFLAGS=”-O3 -no-prec-div -ip -fp-model fast=1 -xSSE2 -axSSE2 -fPIC” \
CXXFLAGS=”${CFLAGS}” \
CPPFLAGS=” -I/usr/alibaba/icc/include ” \
./configure \
–disable-cpu-profiler \
–disable-heap-profiler \
–disable-heap-checker \
–disable-debugalloc \
–enable-minimal \
–enable-frame-pointers && make && make install
echo “/usr/local/lib” > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
第三部:编译安装Percona
CC=icc \
CXX=icpc \
LD=xild \
AR=xiar \
CFLAGS=”-O3 -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free -unroll2 -ip -fp-model fast=1 -restrict -fno-exceptions -fno-rtti -no-prec-div -fno-implicit-templates -static-intel -static-libgcc -static -xSSE2 -axSSE2″ \
CXXFLAGS=”${CFLAGS}” \
CPPFLAGS=” -I/usr/alibaba/icc/include ” \
LDFLAGS=” -L/usr/alibaba/icc/lib/intel/ -lrt -lunwind -ltcmalloc_minimal -lstdc++ ” \
./configure –prefix=/usr/alibaba/install/percona-custom-5.1.55-12.6 \
–with-server-suffix=-alibaba-edition \
–with-mysqld-user=mysql \
–with-plugins=heap,innodb_plugin,myisam,partition \
–with-charset=utf8 \
–with-collation=utf8_general_ci \
–with-extra-charsets=gbk,utf8,ascii \
–with-big-tables \
–with-fast-mutexes \
–with-zlib-dir=bundled \
–with-readline \
–with-pthread \
–enable-assembler \
–enable-profiling \
–enable-local-infile \
–enable-thread-safe-client \
–without-embedded-server \
–with-mysqld-ldflags=-all-static \
–without-query-cache \
–without-geometry \
–without-debug \
–without-ndb-binlog \
–without-ndb-debug
编译完成后make && make install