Lichee_RV学习系列文章目录
Lichee_RV学习系列—认识Lichee Rv Dock、环境搭建和编译第一个程序
Lichee_RV学习系列—移植dhrystone
文章目录
一、stream简介
Stream测试是内存测试中业界公认的内存带宽性能测试基准工具。Stream支持Copy、Scale、Add、Triad四种操作,通过这四种操作进行内存带宽的测试。
二、源码下载
源码可以从Github中进行下载,也可以从官方介绍中进行下载,里面有Linux版本,把Linux版本进行下载即可。
文件的内容如下,核心文件就是stream.c和stream.f,源码是由C和fortran语言编写完成,可以使用gcc或者fortran编译源文件,这里使用gcc
三、文件移植
1、makefile文件编译
将源码中的Makefile进行修改即可,这里提供两个可执行文件,分别是单线程和多线程的方式
#设置编译链路径及工具
CTOOL:=riscv64-unknown-linux-gnu-
CCL:=/home/allwinner/workspace/tina-D1-H/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702
CC:=${CCL}/bin/${CTOOL}gcc
CFLAGS:=-O2 -finput-charset=UTF-8
STFLAGES:=-ffreestanding -DSTREAM_ARRAY_SIZE=10000000 -mabi=lp64d -march=rv64gcxthead -mcmodel=medany -mexplicit-relocs
# 参数介绍
# -mtune=native -march=native 针对CPU指令的优化,此处由于编译机即运行机器。故采用native的优化方法。
# -O3 编译器编译优化级别。
# -mcmodel=medium 当单个Memory Array Size 大于2GB时需要设置此参数(小于2GB时设置无效)。
# -fopenmp 适应多处理器环境,开启后,程序默认线程为CPU线程数。也可以在运行前设置进程数
# 设置方法: export OMP_NUM_THREADS=x x为你想设置的线程数
# -DSTREAM_ARRAY_SIZE=100000000:这个参数是对测试结果影响最大,也是最需要关注的一个参数,指定计算中a[],b[],c[]数组的大小。
# -DNTIMES=20:执行的次数,并且从这些结果中选最优值
all : stream_single_thread stream_multithreading ubuntu
.PHONY:all
#单线程编译
stream_single_thread:stream_single_thread.o
$(CC) $< -o $@
stream_single_thread.o:stream.c
$(CC) $(CFLAGS) -c $< -o $@ ${STFLAGES}
#多线程编译 -- 玄铁C906好像不支持-fopenmp参数
stream_multithreading:stream_multithreading.o
$(CC) $< -o $@ -fopenmp
stream_multithreading.o:stream.c
$(CC) $(CFLAGS) -c $< -o $@ ${STFLAGES} -fopenmp
#ubuntu环境下编译
ubuntu:ubuntu.o
gcc $< -o $@ -fopenmp
ubuntu.o:stream.c
gcc -mtune=native -march=native -O3 -mcmodel=medium -DSTREAM_ARRAY_SIZE=100000000 -DNTIMES=20 -c $< -o $@
#清理规则
.PHONY:clean
clean:
-rm -f stream_single_thread stream_single_thread.o stream_multithreading stream_multithreading.o ubuntu ubuntu.o
这里涉及到挺多设置的,一些是交叉编译工具链的编译配置,一些是stream本身的编译配置,stream本质的编译配置,自己找官方文档看看啦。
点下面链接查看支持Lichee Rv支持什么编译指令:
RISC-V嵌入式开发入门篇1:RISC-V GCC工具链的介绍
对于RISV -V处理器,详解 gcc 编译器,Makefile中gcc编译器参数的含义
编译支持官方文档
也可以使用编译工具链的gcc -v查看支持什么命令,gcc --help查看邦族
Lichee Rv Dock支持使用-v指令的输出,可以看到很多信息。支持语言C、C++、fortran等
cv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=/home/allwinner/workspace/tina-D1-H/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/home/allwinner/workspace/tina-D1-H/prebuilt/gcc/linux-x86/riscv/toolchain-thead-glibc/riscv64-glibc-gcc-thead_20200702/bin/../libexec/gcc/riscv64-unknown-linux-gnu/8.1.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/build/../source/riscv/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --with-mpc=/ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/lib-for-gcc-x86_64-linux/
--with-mpfr=/ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/lib-for-gcc-x86_64-linux/
--with-gmp=/ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/lib-for-gcc-x86_64-linux/
--prefix=/ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/install
--with-sysroot=/ldhome/software/toolsbuild/slave/workspace/riscv64_build_linux_x86_64/install/sysroot
--with-system-zlib
--enable-shared --enable-tls --enable-languages=c,c++,fortran
--disable-libmudflap --disable-libssp --disable-libquadmath --disable-nls --disable-bootstrap --src=../../source/riscv/riscv-gcc
--enable-checking=yes --with-pkgversion='C-SKY RISCV Tools V1.8.4 B20200702'
--enable-multilib --with-abi=lp64d --with-arch=rv64gcxthead 'CFLAGS_FOR_TARGET=-O2 -mcmodel=medany' 'CXXFLAGS_FOR_TARGET=-O2 -mcmodel=medany' CC=gcc CXX=g++
Thread model: posix
gcc version 8.1.0 (C-SKY RISCV Tools V1.8.4 B20200702)
makefile文件移植
运行文件注意要将整个文件夹移植到开发板,主要是中间文件.o需要同时移植过去,不然就会运行出错(我也不知道为什么,只是移植最终文件就会出错,得重新复习一下Makefile和编译的过程了)
一般包含一下文件:cat_gcc只是我存放gcc -v文件的信息,和stream项目无关
四、运行结果
ubuntu下执行的结果:
-------------------------------------------------------------
STREAM version $Revision: 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 100000000 (elements), Offset = 0 (elements)
Memory per array = 762.9 MiB (= 0.7 GiB).
Total memory required = 2288.8 MiB (= 2.2 GiB).
Each kernel will be executed 20 times.
The *best* time for each kernel (excluding the first iteration)
will be used to compute the reported bandwidth.
-------------------------------------------------------------
Your clock granularity/precision appears to be 1 microseconds.
Each test below will take on the order of 656919 microseconds.
(= 656919 clock ticks)
Increase the size of the arrays if this shows that
you are not getting at least 20 clock ticks per test.
-------------------------------------------------------------
WARNING -- The above is only a rough guideline.
For best results, please be sure you know the
precision of your system timer.
-------------------------------------------------------------
Function Best Rate MB/s Avg time Min time Max time
Copy: 2076.6 0.818867 0.770487 0.884801
Scale: 2032.1 0.828582 0.787348 0.904562
Add: 2339.3 1.069185 1.025955 1.135896
Triad: 2332.6 1.092763 1.028905 1.282664
-------------------------------------------------------------
Solution Validates: avg error less than 1.000000e-13 on all three arrays
-------------------------------------------------------------
Lichee 单线程运行结果
-------------------------------------------------------------
STREAM version $Revision: 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 10000000 (elements), Offset = 0 (elements)
Memory per array = 76.3 MiB (= 0.1 GiB).
Total memory required = 228.9 MiB (= 0.2 GiB).
Each kernel will be executed 10 times.
The *best* time for each kernel (excluding the first iteration)
will be used to compute the reported bandwidth.
-------------------------------------------------------------
Your clock granularity/precision appears to be 1 microseconds.
Each test below will take on the order of 186503 microseconds.
(= 186503 clock ticks)
Increase the size of the arrays if this shows that
you are not getting at least 20 clock ticks per test.
-------------------------------------------------------------
WARNING -- The above is only a rough guideline.
For best results, please be sure you know the
precision of your system timer.
-------------------------------------------------------------
Function Best Rate MB/s Avg time Min time Max time
Copy: 1092.9 0.155637 0.146398 0.171233
Scale: 870.7 0.192386 0.183770 0.201332
Add: 937.5 0.262170 0.256007 0.278177
Triad: 915.9 0.272345 0.262036 0.308677
-------------------------------------------------------------
Solution Validates: avg error less than 1.000000e-13 on all three arrays
-------------------------------------------------------------
Lichee 多线程运行结果
./stream_multithreading: error while loading shared libraries: libgomp.so.1: cannot open shared object file: No such file or directory
这个需要libgomp.so库的支持,而我查过最新的gcc编译工具链,也是没有的。估计得拿到源文件自己编译才行,这里我就不搞了,有兴趣的小伙伴可以自己编译(主要是搞了这个移植太久了,不想整了)。使用交叉工具链编译好移植到/usr/lib即可。
五、移植过程中出现的奇奇怪怪的错误以及解决
移植这个搞了很久,竟然搞了两天
,主要问题是集中在编译器指令的设置和Makefile文件的正确编写,以及一个奇怪的问题(在PC机上能够直接执行可执行文件,不管存不存在中间文件.o,而在开发板上面一定要将.o文件放到开发板上,再执行可执行文件才不会出错)。
问题一:出现ELF not found,sysntax error
出现这个问题一般是两个原因:一个是编译文件的工具出错了,可能是将PC机上的文件运行在Lichee Rv板子上面了。
二是:缺少一些库文件(这个是从stack overflow)上看到的回答。我这里乱码了,也不知道为什么。
我这里的问题主要是缺少中间文件.o文件,就会执行出错,解决办法在上面。
问题二:/bin/sh xxx:not found
指令不支持,可能是编译使用了编译不支持的指令,而在编译过程中,编译器并没有发现,这里需要自己看支持什么编译指令。比如使用:使用-march=rv64gc
,而查看编译器,支持的是:-march=rv64gcxthead,这时候就能编译通过,但是编译出来的文件不能执行。
五、参考链接
linux下内存性能测试工具STREAM
STREAM内存带宽测试工具介绍及其内部实现
使用Stream和MLC测试内存性能
对于RISV -V处理器,详解 gcc 编译器,Makefile中gcc编译器参数的含义