前言
首先 specCPU是收费的,好像是800还是1000$,缴费了才有软件分发给你,但是个人或者国内某些项目测试都是百度或者找整机,CPU或者操作系统厂家给。
specCPU和其他性能测试工具类似,基本上都是在被测试机器现场编译测试程序,再运行测试程序得出测试结果以获得最优测试结果。
但specCPU还有个特殊的地方在于除了测试程序外,还自带了一些工具包,在编译specCPU之前,这些工具包得处于可用状态。
所以,如果是完全全新测试,整个测试过程首先是编译工具包,工具包包括好几个工具用于调用或者验证speccpu测试的,比如xz,md5sum perl tar make diff specinvoke。
编译好工具包后,specCPU的编译以及测试是通过runspec来调用和完成的。
因此,全新的specCPU测试需要进行两个部分的编译,分别是
- 工具包的编译
- specCPU的编译
但实际测试过程中,可能存在2种情况:
- 厂家可能给的编译好的针对特定CPU或者机型的,里面已经包含编译好的工具包,可以直接开始runspec运行测试;
- 但对于工作做的更到位的情况,厂家也给你编译好的二进制及相关调用的相应的库文件。可以通过runspec --nobuild 直接开始跑测试。
但是如果要自己编译speccpu工具包以及specCPU,根据官网说明,需要至少满足以下编译器。
Requirements SPEC CPU2006https://www.spec.org/cpu2006/Docs/system-requirements.html#compiler
- For SPECint2006: Both C99 and C++98 compilers
- For SPECfp2006: All three of C99, C++98 and Fortran-95 compilers
编译specCPU工具包
编译speccpu工具包参考如下官网地址:
Tools Build SPEC CPU2006https://www.spec.org/cpu2006/Docs/tools-build.html编译器需求: 官网说明,C99 compiler. Most of the tools are C++ or C89, but XZ is C99.
编译过程很简单,如果在specCPU目录下tools/src下已经有源文件了,直接运行tools/src/buildtools,就可以完成编译了。如果没有源文件,直接从install_archives/cpu2006.tar.xz解压到tools/src下再编译就行。
xz -dc install_archives/cpu2006.tar.xz | tar -xf - tools/src
编译过程会提示perl测试有错,直接y忽略,编译完成后
. ./shrc
runspec -V
进行检查编译是否成功,可以运行runspec --test进行perl的更综合测试。
下一步是编写工具描述文件description
在tools/bin/下新建一个能记住的名字比如linux-uos-aarch64的目录,直接从tools/bin/其他目录拷贝一个description文件到tools/bin/linux-uos-aarch64/下,修改内容,符合当前工具适合的平台描述就行。
最后一步就是打包
. ./shrc
bin/packagetools
直接运行,会自动在specCPU根目录下生成 linux-uos-aarch64-118.tar 这样的压缩包。
将spectar linux-uos-aarch64-118.tar 拷贝到其他未编译specCPU工具的目录下,spectar xf linux-uos-aarch64-118.tar 解压到对应未知后,使用
install.sh -u linux-uos-aarch64
就安装好工具了。
在飞腾2000/4编译过程遇到的坑:
1 make
glob/glob.c:xxx: undefined reference to `__alloca'`×
在编译前面也有警告提示,到连接的时候会报找不到alloca,直接注视掉宏定义的前面和后面,让这个alloca定义上就好了。
// #if !defined __alloca && !defined __GNU_LIBRARY__
# ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
# else /* Not GCC. */
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else /* Not HAVE_ALLOCA_H. */
# ifndef _AIX
# ifdef WINDOWS32
# include <malloc.h>
# else
extern char *alloca ();
# endif /* WINDOWS32 */
# endif /* Not _AIX. */
# endif /* sparc or HAVE_ALLOCA_H. */
# endif /* GCC. */
# define __alloca alloca
// #endif
2 tar specsum
报/stdio.h:474:1: error: 'gets' undeclared here (not in a function); did you mean 'fgets'?
直接给退出了。
直接编辑tar-1.25/gnu/stdio.in.h文件,注视掉#undef gets的两行。
142
143 /* It is very rare that the developer ever has full control of stdin,
144 so any use of gets warrants an unconditional warning. Assume it is
145 always declared, since it is required by C89. */
146 //#undef gets
147 //_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
148
3 timedate test报错
直接修改tools/src/TimeDate-1.20/t/getdate.t文件第159行
my $offset = Time::Local::timegm(0,0,0,1,0,70);
修改为
my $offset = Time::Local::timegm(0,0,0,1,0,1970);
参考unmatched(riscv64)上编译,安装和移植SPEC CPU 2006 - 知乎unmatched系统信息: Linux ubuntu 5.11.0-1021-generic #22-Ubuntu SMP Tue Sep 28 15:19:16 UTC 2021 riscv64 riscv64 riscv64 GNU/Linux Linux version 5.11.0-1021-generic (buildd@riscv64-qemu-lcy01-078) (…https://zhuanlan.zhihu.com/p/429399630
运行测试
实际测试(编译好和未编译好specCPU)都是通过runspec来调用,但实际上最主要的部分在于配置文件的修改。
运行的命令可以简单的用如下格式来:
runspec -c linux-uos-aarch64
这里linux-uos-aarch64对应在config目录下linux-uos-aarch64.cfg内容,所有测试的参数以及优化参数都在这个文件里指定。
简单介绍下specCPU2006的测试情况:
测试主要是测试计算能力,所以基本上只和CPU 内存 编译器参数和优化有关,对磁盘图形等等其他的性能五官
- 测试分为speed和rate两种情况,是通过参数rate指定来确定是那种模式,speed是测试计算机完成单个任务计算能力,rate是测试机器运行多个任务的吞吐量或者速率。 测试结果不带rate的就是speed
- 测试内容分整数和浮点数两项,分别是int fp. 对应测试CINT2006和CFP2006
- 测试还分base peak两项。这个区别在啥地方待查。测试结果不带base的,就是peak。
peak compiled with aggressive optimization for each benchmark. 积极优化
base compiled with conservative optimization for each benchmark. 保守优化
运行参数 :
参数用-n 1 每个测试的运行次数,默认3 ,如果要出报告,需要是3,配置文件用iterations ,
参数用--tune=base或者--tune=all运行是否包括peak 配置文件用tune = base 不包括peak ,all 包括base peak
运行例子:
#运行整数计算能力,int换成fp则计算浮点,换成all表示整数浮点数都运行
runspec --config test.cfg --noreportable int
#可以直接指定某个整数或者浮点数的测试项,这在调整编译优化参数的时候很有用。-n 1表示只运行一次,默认每个测试项会运行三次。
runspec --config mat_dec25j.cfg -n 1 --noreportable 482.sphinx
#只运行base,如果--tune换成all,则base peak都运行
runspec --config mat_dec25j.cfg -n 1 --tune=base --noreportable 482.sphinx
gcc 参数笔记:
-D 定义宏用,如果代码有ifdef可以编译的时候通过-D定义宏来开关,或者 -DNAME=Peter来定义宏的值,但不知道代码里面如果定义了,是代码定义的优先级高还是这里的搞。
-l (小写L) 是指要链接的库名,如果是-lz 表示连接libz ,如果还加了-static 则寻找libz.a静态库。
-L 表示寻找库的目录,-I (大写i) 表示寻找头文件的目录
-lz 压缩库(Z)
-lrt 实时库(real time):shm_open系列
-lm 数学库(math)
-lc 标准C库(C lib)
-dl ,是显式加载动态库的动态函数库
编译403.gcc遇到的问题
如果指定了-static的优化参数,/usr/bin/ld: cannot find -lm
需要补充yum install glibc-static libgfortran-static
据说用gcc9会获得更好的成绩。
配置文件
配置文件和命令行优先级关系:
配置文件内命名选项 > 命令行 > 配置文件头部选项
配置文件的主要三个组成部分:
头部选项:绝大部分选项都在头部
用户定义的命名选项 :用于定义编译的时候各种优化参数
命名选项基本格式由四个部分组成,
benchmark[,...]=tuning[,...]=extension[,...]=machine[,...]:
- benchmark可以是default int fp 以及单独的测试项如403.gcc
- tuning 可以是default base peak
- extension 可以是default 或者任意的字符串
- machin 可以是default 或者任意字符串
对于组成部分后面全是default的,可以省略,比如:
403.gcc=base=default: 403.gcc=base:
是相同的
具体测试的时候,命名选项内包含的参数优先级按命名的详细成都来确定的,命名选项名称指定的越具体,则编译的时候使用优先级越高。
$ cat tmp.cfg
runlist = sjeng
size = test
iterations = 1
tune = base
output_format = text
teeout = 1
default=default=default=default:
OPTIMIZE = -xO2 -w
int=default=default=default:
OPTIMIZE = -xO3 -w
$ runspec --config=tmp | grep sjeng.c
cc -c -o sjeng.o -DSPEC_CPU -DNDEBUG -xO3 -w sjeng.c
$
抄个官网的例子,上面的例子重,最终在测试的时候,编译选项使用的
int=default=default=default:部分定义的-xO3 ,是因为int=default=default=default:指定的比default=default=default=default:更具体。如果还有458.sjeng=default=default=default:这样的命名选项部分,那458.sjeng=default=default=default:下面跟的参数优先级更高,如果文件中出现重复的
458.sjeng=default=default=default:那谁排后面谁的优先级更高。
上面的情况对于命名选项的第二个部分也是一样的原理。
除了用benchmark和tune来命名,还可以用自定义extension名称来指定优化选项,从而在命令行可以指定--extension=xxx来使用extension部分的命名,下面再抄一个官网例子。
$ cat tmp.cfg
runlist = sjeng
size = test
iterations = 1
tune = base
output_format = text
teeout = 1
default=default=default:
LIBS = -lslowmalloc
default=default=myke:
LIBS = -lbsdmalloc
default=default=yusuf:
LIBS = -lthread -lmtmalloc
$
$ runspec --config=tmp --extension=myke | grep sjeng.o
cc -c -o sjeng.o -DSPEC_CPU -DNDEBUG sjeng.c
cc attacks.o book.o crazy.o draw.o ecache.o epd.o eval.o leval.o moves.o
neval.o partner.o proof.o rcfile.o search.o see.o seval.o sjeng.o ttable.o
utils.o -lbsdmalloc -o sjeng
$
$ runspec --config=tmp --extension=yusuf | grep sjeng.o
cc -c -o sjeng.o -DSPEC_CPU -DNDEBUG sjeng.c
cc attacks.o book.o crazy.o draw.o ecache.o epd.o eval.o leval.o moves.o
neval.o partner.o proof.o rcfile.o search.o see.o seval.o sjeng.o ttable.o
utils.o -lthread -lmtmalloc -o sjeng
$
$ cd $SPEC/benchspec/CPU2006/458.sjeng/exe
$ ls -lt | head -3
total 5888
-rwxrwxr-x 1 alan staff 244688 May 11 16:32 sjeng_base.yusuf
-rwxrwxr-x 1 alan staff 244628 May 11 16:31 sjeng_base.myke
可以看到这里不光编译选项使用了自定义的,生成的spec二进制文件后缀也应用上了。
如果多个命名选项部分并无冲突,那,几个部分的编译参数都会合并应用到测试编译上(当然有相同参数的,以命名选项最详细的参数为高优先级)。
如果不同的命名选项参数有冲突,优先级如下:
benchmark > suite(官网例子就是去掉测试号的benchmark,比如bzip2,虽然指定benchmark是401.bzip2) > tune > extension
MD5部分: (用于校验编译好的specCPU测试的二进制是不是和cfg的值匹配,不匹配应该要重新编译)这部分不用管,测试的时候会自动更新进去的。
其他
要跑好specCPU其实最主要还是对cpu以及编译器的细节要熟悉,才知道调整哪些编译选项是有用的,所以一般都是找CPU厂商 提供cfg,实际自己跑一跑就是了,最多优化下内存,比如双通道,或者BIOS放开了内存的参数调整,可以细调下内存参数。
如果对gcc优化参数不了解,会出现跑不过的情况,反正我目前遇到是不加优化参数gcc测试都跑不过,借鉴别人的cfg,浮点部分有一个benchmark,base跑不过(编译通过但运行的时候直接报非0错误退出)但peak反而跑过了。很是费解,要学习的东西太多了。
以上内容是自己测着玩的笔记,后面遇到有新的东西再做补充。