diff --git a/articles/20230510-vf2-spec06.md b/articles/20230510-vf2-spec06.md
new file mode 100644
index 0000000000000000000000000000000000000000..05cfad04f69be6f620cd4cf50245f1ec96bf566d
--- /dev/null
+++ b/articles/20230510-vf2-spec06.md
@@ -0,0 +1,310 @@
+> Corrector: [TinyCorrect](https://gitee.com/tinylab/tinycorrect) v0.1 - [tounix spaces toc codeinline tables urls pangu]
+> Author: Kepontry
+> Date: 2023/5/10
+> Revisor: Falcon
+> Project: [RISC-V Linux 内核剖析](https://gitee.com/tinylab/riscv-linux)
+> Proposal: [VisionFive 2 开发板软硬件评测及软件 gap 分析](https://gitee.com/tinylab/riscv-linux/issues/I64ESM)
+> Sponsor: PLCT Lab, ISCAS
+
+# VisionFive 2 开发板的 SPEC2006 评测
+
+## 简介
+
+### SPEC 2006
+
+SPEC CPU 2006 是 SPEC 公司推出的工业标准化的 CPU 密集型测试套件,用于评测系统的处理器、内存子系统和编译器。该测试套件包括 SPECint 和 SPECfp 两个子测试,SPECint 包含 12 个测试程序,用于测试定点性能;SPECfp 包含 17 个测试程序,用于测试浮点性能。
+
+## 构建工具软件
+
+首先从官网下载 SPEC 2006 测试代码并解压。SPEC 提供了一些预构建的工具软件来保证跨平台的操作一致性。但由于这些预构建软件不支持 RISC-V 架构,需要手动编译。在 `tools/src` 目录下,SPEC 提供了一个 `buildtools` 脚本可用于自动构建工具软件,但直接执行显示未能识别操作系统类型。
+
+```shell
+$ tar -xvf speccpu2006-v1.0.1-newest.tar
+$ export SPEC_DIR=/root/speccpu2006-v1.0.1
+$ export TOOLS_SRC=$SPEC_DIR/tools/src
+$ cd $TOOLS_SRC
+$ ./buildtools
+This script, last modified 2002-09-03, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+......
+
+UNAME_MACHINE = riscv64
+UNAME_RELEASE = 5.15.0
+UNAME_SYSTEM = Linux
+UNAME_VERSION = #9 SMP Mon May 1 14:51:30 UTC 2023
+configure: error: cannot guess build type; you must specify one
+```
+
+根据提示,需要更新 `config.guess` 和 `config.sub` 文件,用于猜测规范的操作系统名称。由于官网地址已失效,使用新地址进行下载。
+
+```shell
+$ cd $SPEC_DIR
+$ wget -O config.guess 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
+$ wget -O config.sub 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
+```
+
+使用 find 命令查找用到 `config.sub` 文件的位置,并用上面下载的新文件覆盖。`config.guess` 文件也按同样的方法更新。
+
+```shell
+$ find . -name "config.sub"
+./tools/src/tar-1.15.1/config/config.sub
+./tools/src/expat-1.95.8/conftools/config.sub
+./tools/src/make-3.80/config/config.sub
+./tools/src/specinvoke/config.sub
+```
+
+接着继续运行 buildtools 脚本,报错信息显示 `__alloca` 和 `__stat` 函数未定义。
+
+```shell
+$ cd $TOOLS_SRC
+$ ./buildtools
+/usr/bin/ld: glob.o: in function `.L0 ':
+glob.c:(.text+0x46e): undefined reference to `__alloca'
+```
+
+这是因为 SPEC 保留了一份 glob 代码,以保证在没有 C 库的系统上也能运行。当检测到系统没有 C 库或 glob 接口版本不一致时,将使用 SPEC 中的代码。SPEC 代码中 `__alloca` 和 `__stat` 函数的定义被 `__GNU_LIBRARY__` 宏检测代码包裹,仅当该宏未被定义时定义这两个函数。以前 glob 接口版本是 1,接口版本一致,使用 SPEC 提供的 glob 代码表示系统没有 C 库,所以这两个函数被定义。但 glob 接口版本现在升级到 2,由于接口版本不一致,所以使用 SPEC 提供的 glob 代码,但 `__GNU_LIBRARY__` 宏被定义,导致所需的 `__alloca` 和 `__stat` 函数未定义。解决方法是将 `make-3.80/glob/glob.c` 代码文件中 `__alloca` 和 `__stat` 函数定义前的 `#ifndef__GNU_LIBRARY__` 及对应 `#endif` 宏检测代码注释掉,以使用 SPEC 定义的函数,即可成功运行 buildtools 脚本。
+
+## 测试程序安装与运行
+
+### 测试程序安装
+
+成功构建工具软件后,需要将其打包,以供安装脚本使用。
+
+```shell
+$ cd $SPEC_DIR
+$ source shrc
+$ packagetools linux-riscv64
+......
+tools/bin/linux-riscv64/unbundled
+tools/bin/linux-riscv64/specmd5sum
+tools/bin/linux-riscv64/cpu2006tools-linux-riscv64.tar.bz2
+
+*******************************************************************
+
+The tarball to submit for inclusion in the distribution is
+
+linux-riscv64-098a.tar
+
+ABSOLUTELY DO NOT submit the tarball in tools/bin/linux-riscv64
+as it is not complete.
+
+*******************************************************************
+```
+
+运行安装脚本,安装 SPEC 2006。
+
+```shell
+$ ./install.sh
+SPEC CPU2006 Installation
+
+Top of the CPU2006 tree is '/root/speccpu2006-v1.0.1'
+
+There appears to be only one valid toolset:
+
+linux-riscv64
+
+Use this? (y/n)
+y
+
+Checking the integrity of your source tree...
+
+Checksums are all okay.
+Removing previous tools installation
+Unpacking binary tools for linux-riscv64...
+Checking the integrity of your binary tools...
+
+Checksums are all okay.
+Top of SPEC benchmark tree is '/root/speccpu2006-v1.0.1'
+Everything looks okay. cd to /root/speccpu2006-v1.0.1,
+source the shrc file and have at it!
+```
+
+### 编译与运行
+
+将示例配置 example-medium.cfg 拷贝一份,命名为 riscv64.cfg,并指定 C、C++和 Fortran 语言的编译器和优化参数。
+
+```shell
+$ cp config/example-medium.cfg config/riscv64.cfg
+$ vim config/riscv64.cfg
+......
+CC = gcc
+CXX = g++
+FC = gfortran
+
+int=base:
+OPTIMIZE = -O2
+COPTIMIZE = -O2
+CXXOPTIMIZE = -O2
+
+fp=base:
+OPTIMIZE = -O2
+COPTIMIZE = -O2
+CXXOPTIMIZE = -O2
+FOPTIMIZE = -O2
+```
+
+执行 runspec 命令,编译并运行程序。常用的命令有以下三条,分别用于正式测试前的功能性测试,单应用测试和正式测试。
+
+```shell
+$ source shrc
+# 在 test 数据集上测试应用是否能正常编译运行
+$ runspec -c riscv64.cfg -i test -n 1 all -I --tune=base
+# gamess 应用测试
+$ runspec -c riscv64.cfg -i test -n 1 416 -I --tune=base --noreportable
+# 定点正式测试
+$ runspec -c riscv64.cfg -i ref -n 3 int -I --tune=base
+```
+
+各参数的作用如下:
+
+* -c: 指定使用的编译配置文件,位于 config 目录下
+* -i: 指定数据集大小,ref/train/test 分别表示规模为大/中/小的数据集,test 常用于正确性测试,ref 用于正式测试
+* -n: 运行次数,生成报告需要该值大于等于 3,默认值为 3
+* all/int/fp/416: 运行所有/定点/浮点/gamess 测试,运行单应用测试时要添加--noreportable 参数
+* -I: 跳过发生执行错误的用例
+* --tune: 可以指定为 base 或 peak,分别对应配置文件中不同的编译选项
+
+## 报错解决方案
+
+由于编程语言标准和执行环境的变化,一些测试程序在编译和运行过程中会报错,需要添加编译参数。
+
+### 编译报错
+
+- memset 等字符串函数未定义:483.xalancbmk、447.dealII
+
+ 添加 cstring 库。
+
+- Type mismatch 报错:416.gamess 和 481.wrf
+
+ 添加-std=legacy 选项,兼容老的 fortran 语法。
+
+- no known conversion 报错:450.soplex
+
+ 添加-std=c++03 选项,兼容老的 c++语法。
+
+- 禁止指针与整数的比较:447.dealII
+
+ 代码书写不严谨,添加-fpermissive 选项从而允许比较。
+
+- atoi 函数重复定义、`nf_*` 库函数未定义:400.perlbench
+
+ 开启编译优化后会造成上述错误,添加-std=gnu89 选项可解决上述问题。
+
+### 运行时报错
+
+- IEEE_UNDERFLOW_FLAG 浮点异常:416.gamess
+
+ 由于循环优化导致,需要添加-fno-aggressive-loop-optimizations,以关闭激进的循环优化。
+
+- Miscompare 报错,运行结果不一致:464.h264ref、482.sphinx3
+
+ 编译器默认将 char 解释为 unsigned 类型,添加-fsigned-char,将其改为 signed 类型。
+
+### 无报错配置
+
+在 riscv64.cfg 配置文件中添加以下兼容编译选项后,可以解决上述编译和运行时报错。
+
+```shell
+#######################################################################
+# Integer Portability
+
+int=default=default=default:
+PORTABILITY = -DSPEC_CPU_LP64
+
+400.perlbench=default=default=default:
+CPORTABILITY = -DSPEC_CPU_LINUX_X64 -std=gnu89
+
+462.libquantum=default=default=default:
+CPORTABILITY = -DSPEC_CPU_LINUX
+
+464.h264ref=default=default=default:
+CPORTABILITY = -fsigned-char
+
+483.xalancbmk=default=default=default:
+CXXPORTABILITY = -DSPEC_CPU_LINUX -include cstring
+
+#######################################################################
+
+fp=default=default=default:
+PORTABILITY = -DSPEC_CPU_LP64
+
+416.gamess=default=default=default:
+FPORTABILITY = -std=legacy -fno-aggressive-loop-optimizations -flto
+
+436.cactusADM=default=default=default:
+FPORTABILITY = -fno-second-underscore
+
+447.dealII=default=default=default:
+CXXPORTABILITY = -DSPEC_CPU_TABLE_WORKAROUND -fpermissive -include cstring
+
+450.soplex=default=default=default:
+CXXPORTABILITY = -std=c++03
+
+481.wrf=default=default=default:
+FPORTABILITY = -std=legacy
+CPORTABILITY = -DSPEC_CPU_LINUX -DSPEC_CPU_CASE_FLAG
+
+482.sphinx3=default=default=default:
+CPORTABILITY= -fsigned-char
+
+#######################################################################
+```
+
+## 结果与对比
+
+下表展示了 SPECint2006 的三轮测试结果,最终得分为各子项取中位数后的几何平均,JH7110 SoC 在频率为 1.5GHz,编译优化选项为 `-O2` 下的 SPECint2006 单核得分为 4.62 分。测试共耗时一天完成,由于三次执行差别不大,如果想尽快完成测试,可以考虑仅执行一次。
+
+| SPECint2006 | 耗时(秒) | 得分 | 耗时(秒) | 得分 | 耗时(秒) | 得分 |
+|----------------|----------|------|----------|------|----------|------|
+| 400.perlbench | 1950 | 5.02 | 1930 | 5.05 | 1950 | 5.02 |
+| 401.bzip2 | 2640 | 3.65 | 2640 | 3.65 | 2640 | 3.66 |
+| 403.gcc | 1710 | 4.71 | 1720 | 4.68 | 1710 | 4.7 |
+| 429.mcf | 3620 | 2.52 | 3620 | 2.52 | 3610 | 2.52 |
+| 445.gobmk | 1500 | 6.97 | 1510 | 6.96 | 1510 | 6.97 |
+| 456.hmmer | 2270 | 4.1 | 2280 | 4.09 | 2280 | 4.09 |
+| 458.sjeng | 2080 | 5.81 | 2090 | 5.78 | 2100 | 5.77 |
+| 462.libquantum | 2480 | 8.36 | 2510 | 8.26 | 2590 | 7.99 |
+| 464.h264ref | 3630 | 6.09 | 3630 | 6.1 | 3640 | 6.07 |
+| 471.omnetpp | 2130 | 2.94 | 2110 | 2.96 | 2120 | 2.94 |
+| 473.astar | 1780 | 3.95 | 1780 | 3.95 | 1780 | 3.95 |
+| 483.xalancbmk | 1520 | 4.53 | 1500 | 4.6 | 1520 | 4.54 |
+
+下表展示了 SPECfp2006 的三轮测试结果,最终得分为 2.92 分,测试耗时两天完成。
+
+| SPECfp2006 | 运行时长 | 得分 | 运行时长 | 得分 | 运行时长 | 得分 |
+|---------------|----------|------|----------|------|----------|------|
+| 410.bwaves | 5030 | 2.7 | 5030 | 2.7 | 5040 | 2.7 |
+| 416.gamess | 5510 | 3.55 | 5490 | 3.56 | 5500 | 3.56 |
+| 433.milc | 3040 | 3.02 | 3030 | 3.03 | 3050 | 3.01 |
+| 434.zeusmp | 3730 | 2.44 | 3730 | 2.44 | 3720 | 2.45 |
+| 435.gromacs | 1940 | 3.68 | 1940 | 3.68 | 1940 | 3.69 |
+| 436.cactusADM | 5480 | 2.18 | 5520 | 2.17 | 5490 | 2.17 |
+| 437.leslie3d | 5090 | 1.85 | 5100 | 1.84 | 5120 | 1.84 |
+| 444.namd | 2050 | 3.91 | 2060 | 3.89 | 2050 | 3.91 |
+| 447.dealII | 1930 | 5.93 | 1980 | 5.78 | 1930 | 5.94 |
+| 450.soplex | 2400 | 3.47 | 2390 | 3.49 | 2410 | 3.46 |
+| 453.povray | 1160 | 4.58 | 1160 | 4.59 | 1160 | 4.59 |
+| 454.calculix | 6910 | 1.19 | 6910 | 1.19 | 6910 | 1.19 |
+| 459.GemsFDTD | 4640 | 2.29 | 4650 | 2.28 | 4620 | 2.3 |
+| 465.tonto | 2660 | 3.7 | 2670 | 3.69 | 2670 | 3.68 |
+| 470.lbm | 7630 | 1.8 | 7640 | 1.8 | 7620 | 1.8 |
+| 481.wrf | 3920 | 2.85 | 3950 | 2.83 | 3930 | 2.84 |
+| 482.sphinx3 | 4740 | 4.11 | 4770 | 4.09 | 4770 | 4.09 |
+
+根据[第三方测试结果][002](PPT 的第 11 页),SiFive U54 在裸金属环境下,频率为 1.5GHz 的 SPECint2006 得分大约为 3.4。JH7110 SoC 采用的是 U74 核心,频率也为 1.5GHz,在操作系统上的 SPECint2006 得分为 4.62 分,性能表现优于 U54。但 U74 是顺序双发射处理器,性能要弱于大部分的乱序处理器,例如[香山开源处理器][001]的初代芯片“雁栖湖”是一个乱序六发射处理器,在 1.3GHz 的频率下,SPECint2006 得分接近 10 分。
+
+## 总结
+
+本文探究了 SPEC CPU 2006 测试套件在 RISC-V 架构处理器上的运行方法,并对 VisionFive 2 开发板的性能进行评测与对比分析。结果显示,其在 CPU 频率为 1.5GHz,编译优化选项为 `-O2` 下的 SPECint2006 得分为 4.62 分,SPECfp2006 得分为 2.92 分。
+
+## 参考资料
+
+- [SPEC 2006 使用流程][003]
+
+[001]: https://github.com/OpenXiangShan/XiangShan
+[002]: https://riscv.org/wp-content/uploads/2019/02/CloudBEAR_Processor_IP_Product_Line.pdf
+[003]: https://www.francisz.cn/2021/10/04/spec2006-usage/