Ubuntu 下使用 Scons 交叉编译嘉楠堪智 CanMV K230 大小核 Coremark 程序

news2024/9/21 4:22:28

在 Ubuntu 下使用 SCons 进行交叉编译嘉楠堪智 CanMV K230 大小核(不同的玄铁 C908 核心)的 C 程序,以 Coremark 程序为例,顺便测试一下大小核和编译器的性能。

2024年3月14日,嘉楠科技宣布推出了全球首款支持 RISC-V Vector 1.0 标准的商用量产端侧 AIoT 芯片 K230,我们顺便了解一下其采用的玄铁 C908 核心,并测试一下实际的表现。

玄铁 C908 采用 9 级双发按序流水线,典型工作频率>2GHz,通过指令融合技术进一步提升流水线效率,实现了卓越的能效比。兼容 RVA22 标准,同时兼容 RISC-V 最新 Vector1.0 标准以进一步提升 AI 算力。可以应用在行业 IPC、智能交互、AR/VR、无线通讯等场景。

阿里 T-Head 提供了与 C906 单发按序处理器的性能对比:

玄铁 C908 的运行频率最高可达 2GHz,采用的是台积电 12 纳米工艺,单核动态功耗低至 52.8mW/GHz。在相同频率和工艺限制的典型场景下,玄铁 C908 的能效比玄铁 C906 提升了 20% 以上。

RISC-V Vector Extension 1.0 确实有助于 AI 工作负载,在相同条件下,对使用 INT4 数据类型的唤醒词检测、图像分类、关键字定位和 MLPerf 微型 V0.7 推理性能测试的异常检测中,C908 比 C906 快了大约 2 到 3.5 倍。

一、安装 SCons

可以使用 apt 包管理器安装 SCons:

        sudo apt update

        sudo apt install scons

二、准备交叉编译工具链

k230_sdk 中提供了工具链,buildroot package 和 AI package,可用如下命令下载:

        cd k230_sdk

        source tools/get_download_url.sh && make prepare_sourcecode

嘉楠堪智 CanMV K230 大小核是不同的玄铁 C908 核心,嘉楠给出了不同的工具链:

  •     大核 rt-samrt 工具链:

        k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu

这个工具链使用 Musl libc 作为 C 标准库,而不是更常见的 glibc。Musl libc 是一种轻量级的 C 库,旨在提供与 glibc 类似的 API,但更小、更快、更简单,非常适合嵌入式系统或需要减少程序大小的环境。

  •     小核 linux 工具链:

        k230_sdk/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0

这个工具链使用 glibc 作为 C 标准库。glibc 是 Linux 系统上最常用的 C 标准库,提供了丰富的功能和良好的兼容性。

也可通过以下链接下载工具链:

wget https://download.rt-thread.org/rt-smart/riscv64/riscv64-unknown-linux-musl-rv64imafdcv-lp64d-20230222.tar.bz2


wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1659325511536/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0-20220715.tar.gz

三、准备 Coremark 程序

1. 下载代码

        git clone https://github.com/eembc/coremark.git

        cd coremark/

2. 移植代码

将 simple 目录下的 core_portme.c 和 core_portme.h 拷贝到当前 coremark 目录下,按照下面做修改:

四、编写 SConstruct 文件

SConstruct 文件是 SCons 的构建脚本。编写一个 SConstruct 文件,指定源文件、构建目标、编译器和其他构建选项。

1. 小核 Linux 的 SConstruct 文件

如下所示:

# 引入SCons的环境  
import os  
  
# 交叉编译工具链的路径  
toolchain_path = '/home/xu/k230_sdk/toolchain/Xuantie-900-gcc-linux-5.10.4-glibc-x86_64-V2.6.0/bin'  
  
# 设置环境变量  
env = Environment(ENV={'PATH' : os.environ['PATH'] + ':' + toolchain_path})  
  
# 设置交叉编译器  
env['CC'] = 'riscv64-unknown-linux-gnu-gcc'  
env['LINK'] = '$CC'  
  
# 添加编译和链接选项(根据你的需要调整)  
#env['CFLAGS'] = ['-mcmodel=medany', '-march=rv64imafdcv', '-mabi=lp64d']  
#env['LINKFLAGS'] = env['CFLAGS']  

env.Append(CCFLAGS=['-O2'])
#env.Append(DEFS=['PERFORMANCE_RUN=1', 'ITERATIONS=100000'])

# 假设你的CoreMark源文件在'src'目录下  

src_files = Glob('*.c') 
  
# 构建程序(假设你的目标文件名为'coremark')  
env.Program(target='coremark_linux.elf', source=src_files)

2. 大核 RT- smart 的 SConstruct 文件:

如下所示:

# 引入SCons的环境  
import os  
  
# 交叉编译工具链的路径  
toolchain_path = '/home/xu/k230_sdk/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin'  
  
# 初始化环境变量  
env = Environment(tools=['default', 'gcc'], ENV={'PATH' : os.environ['PATH'] + ':' + toolchain_path})  
  
# 设置交叉编译器  
env['CC'] = 'riscv64-unknown-linux-musl-gcc'  
env['LINK'] = '$CC'  
#设置编译器标志
env.Append(CCFLAGS=['-O2','-mcmodel=medany', '-march=rv64imafdcv', '-mabi=lp64d'])
#设置链接器标志
env.Append(LINKFLAGS=['-mcmodel=medany', '-march=rv64imafdcv', '-mabi=lp64d',
                     '-T', '/home/xu/k230_sdk/src/big/mpp/userapps/sample/linker_scripts/riscv64/link.lds',
                     '-L/home/xu/k230_sdk/src/big/rt-smart/userapps/sdk/rt-thread/lib',
                     '-Wl,--whole-archive', '-lrtthread', '-Wl,--no-whole-archive',
                     '-n', '--static'])
                     
env['CPPPATH'] = ['#']  # 如果有头文件路径需要添加  
env['LIBPATH'] = [  
#    '/home/xu/k230_sdk/src/big/rt-smart/userapps/sdk/rt-thread/lib',  
    '/home/xu/k230_sdk/src/big/rt-smart/userapps/sdk/lib/risc-v/rv64',  
    '/home/xu/k230_sdk/src/big/rt-smart/userapps/sdk/rt-thread/lib/risc-v/rv64'  
]  
env['LIBS'] = ['rtthread']  
env['RPATH'] = []  # 如果有需要添加的运行时搜索路径  
  
# 添加源文件  
src_files = Glob('*.c')  # 假设CoreMark源文件在目录下  
  
# 设置链接选项(针对-Wl, --whole-archive 和 -Wl, --no-whole-archive)  
#env.Append(LINKFLAGS=['-Wl,--whole-archive', '-lrtthread', '-Wl,--no-whole-archive'])  
#env.Append(LINKFLAGS=['-Wl,--start-group', '-lrtthread', '-Wl,--end-group'])  
  
#编译源文件
#objects = [env.Object(file) for file in src_files]
  
# 构建程序  
env.Program(target='coremark_rt.elf', source=src_files)  
  
# 如果需要额外的构建步骤或目标,可以在这里添加

 编译参数:

  • -mcmodel=medany:

    • mcmodel 代表“代码模型”(code model)。在 RISC-V 架构中,代码模型决定了代码和数据的布局方式,以及编译器如何生成对它们的引用。
    • medany 程序及其静态定义的符号必须位于单个4 GiB地址范围内。使用 auipc 和 addi 指令对来生成地址。使用 auipc 指令取符号地址的高 20 位。auipc 配合其它包含低 12 位立即数的指令后,可以访问当前 PC 的前后 2GiB (PC - 2GiB ~ PC + 2GiB) 的地址空间。程序可以是静态链接或动态链接。
    • medlow 程序及其静态定义的符号必须位于单个2 GiB地址范围内,并且必须位于 -2 GiB 到 +2 GiB 的绝对地址之间。使用 lui 和 addi 指令对来生成地址。使用 lui 指令取符号地址的高 20 位。 lui 配合其它包含低 12 位立即数的指令后,可以访问的地址空间是 -2GiB ~ 2GiB。程序可以是静态链接或动态链接。

  • -march=rv64imafdcv:

    • march 标志用于指定RISC-V架构的版本或变种。
    • rv64imafdcv 指示编译器生成针对64位RISC-V(RV64)的代码,并且包含I(基本整数指令集)、M(乘法/除法指令)、A(原子指令)、F(单精度浮点指令)、D(双精度浮点指令)、C(压缩指令集)和V(向量指令集)等指令集的代码。
    • 这个选项确保你的代码可以利用 RISC-V 的这些特定功能,从而可能提供更好的性能或功能。
  • -mabi=lp64d:

    • mabi 标志用于指定应用程序二进制接口(ABI)。ABI 定义了如何在机器代码级别上调用函数、传递参数、返回结果以及数据的内存布局。
    • lp64d 是一种ABI,其中 “lp64” 表示 longs 和指针都是 64 位,而 “d” 表示双精度浮点数是 64 位。这是 RISC-V 架构中常用的 ABI 之一,它提供了与许多其他 64 位架构(如x86_64)相似的数据模型。

五、运行 Scons 编译:

进入 k230_sdk/src/big/rt-smart/userapps 目录,编译程序:

xu@HP:~/k230_sdk/src/big/rt-smart/userapps$scons --directory=coremark

小核 Linux 编译:

大核 RT- smart  编译:

六、运行 coremark:

标号为 USB 的端口连接到电脑后,会识别为 U 盘 CanMV ,把产生的文件拷贝到 U 盘上:

在串口终端里,ttyACM1 对应 Linux 小核,ttyACM2 对应 rt-smart 大核,可以通过 sharefs 目录交换文件:

小核 Linux 执行程序:

        ./coremark_linux.elf

大核 RT- smart 执行程序:

        msh /sdcard/app>./coremark_rtO3.elf

七、小结:

阿里 T-Head 表示,玄铁 C908 的性能介于 2020 年和 2019 年分别推出的 C906 和 C910 内核之间。玄铁 C906 的 coremark 分数是:3.40 CoreMark/MHz,玄铁 C910 的 coremark 分数是:7.10 CoreMark/MHz,StarFive U74 的 coremark 分数是:5.09 CoreMark/MHz,玄铁 C908 小核的 coremark 分数是:4.29 CoreMark/MHz?

嘉楠堪智 CanMV K230 800MHz 小核的 coremark 分数是:3433(4.29 CoreMark/MHz),1.6GHz 大核的 coremark 分数是:4522(2.83 CoreMark/MHz)?(不知道哪个设置有问题,应该是:8368(5.23 CoreMark/MHz))

                                                                                         老徐,2024/5/8

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1666593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

掌握未来搜索的钥匙:深入解析 Milvus 向量搜索引擎的终极指南!

在大数据时代,向量搜索技术愈发重要。作为一个开源的向量相似性搜索引擎,Milvus 提供了基于向量的相似性搜索功能,广泛应用于机器学习、人工智能等领域。本文将深入介绍 Milvus 的基本概念,包括其介绍、主要作用、使用方法及注意事…

【iOS开发】—— 初识锁

【iOS开发】—— 初识锁 线程安全锁的种类自旋锁定义原理自旋锁缺点OSSpinLock(自旋锁) 互斥锁os_unfair_lockpthread_mutexNSLockNSRecusiveLockSemaphore信号量synchronized 总结两种之间的区别和联系: 线程安全 当一个线程访问数据的时候…

深入理解WPF的ResourceDictionary

深入理解WPF的ResourceDictionary 介绍 在WPF中,ResourceDictionary用于集中管理和共享资源(如样式、模板、颜色等),从而实现资源的重用和统一管理。本文详细介绍了ResourceDictionary的定义、使用和合并方法。 定义和用法 Res…

Android Hanlder 揭密之路- 深入理解异步消息传递机制Looper、Handler、Message三者关系

在Android开发中,Handler作为实现线程间通信的桥梁,扮演着至关重要的角色。无论是在主线程执行UI操作,还是在子线程进行耗时任务,Handler都可以高效地将异步消息分派到对应的线程中执行。 本文将全方位解析Handler的工作原理及实现…

2024数维杯数学建模C题思路代码

2024年数维杯&电工杯思路代码在线文档​https://www.kdocs.cn/l/cdlol5FlRAdE 这道题想要做出好的结果,必须要结合插值法和分布函数来做,主要还是因为勘探点太少,直接用插值法效果不太好,以下是我做的,函数分布可…

Python的while循环

目录 while循环的结构 示例 关键字 break continue while循环的结构 while condition(循环条件): # 循环的内容 循环内容的执行与结束需要通过循环条件控制。 在执行循环之前需要设立一个循环条件的初始值,以便while循环体判断循环条件。…

Loongnix系统替换内核操作

Loongnix系统替换内核操作 一、终端下执行命令 sudo apt search linux-image* 返回结果中格式如: linux-image-4.19.0-19-loongson-3 为最新的内核源码。 二、下载内核源码包 sudo apt source linux-image-4.19.0-19-loongson-3 如提示:E: 您必须在 sources.li…

网络安全等级保护的发展历程

1994年国务院147号令第一次提出,计算机信息系统实行安全等级保护,这也预示着等保的起步。 2007年《信息安全等级保护管理办法》的发布之后。是等保在各行业深耕落地的时代。 2.0是等保版本的俗称,不是等级。等保共分为五级,二级…

C#语音播报(通过CoreAudioAPI完成对扬声器的控制)

1,效果: 作用: 可对当前内容(例如此例中的重量信息)进行语音合成播报 。可设置系统扬声器音量与状态(是否静音),同时根据扬声器状态同步更新当前控件状态与值,实现强制PC扬声器按照指定的音量进行播报&…

Ansible常用变量【上】

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。 在Ansible中会用到很多的变量,Ansible常用变量包括以下几种: 1. 自定义变量——在playbook中用户自定义…

函数重载和函数模板

c语言中函数名字不可重复,但是可以写代码实现 普通的函数重载 这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同和返回值没有关系(因为就像我想调用Add(1,2),Add重载的几个函数仅仅返回值不同,编辑器就不知道去找哪一个,就有歧义了) 情况1-数组 int ave(int*pa,i…

用 Supabase CLI 进行本地开发环境搭建

文章目录 (零)前言(一)Supabase CLI(1.1)安装 Scoop(1.2)用 Scoop 安装 Supabase CLI (二)本地项目环境(2.1)初始化项目(2…

【全开源】微凌客洗护小程序FastAdmin+Uniapp(源码搭建/上线/运营/售后/维护更新)

一款基于FastAdminUniapp开发的洗护小程序系统,适用于线上下单到店核销的业务场景,拥有会员卡、优惠券、充值提现、商户管理等功能,提供Uniapp后台无加密源代码。 线上线下融合:微凌客洗护小程序适用于线上下单到店核销的业务场景…

nacos命名空间的配置

给微服务配置namespace 给微服务配置namespace只能通过修改配置来实现。 例如,修改order-service的application.yml文件: spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZnamespace: 492a7d5d-237b-46a1-a99a-fa8e98e4b0f…

C语言数据结构 - 选择题集合(二叉树)

一生负气成今日 四海无人对夕阳 目录 树的专辑 树的专辑 1.有n个元素的完全二叉树的深度是( ) A.nlogn B.nlogn1 C.logn D.logn1 答案:D 解析: 设完全二叉树的节点数为 N,高度为 h ,高度为 h 时空的结点…

python零基础知识 - 定义列表的三种方式,循环列表索引值

这一小节,我们将从零基础的角度看一下,python都有哪些定义列表的方式,并且循环这个列表的时候,怎么循环,怎么循环他的索引值,怎么拿到的就是元素值。 说完循环,我们会说一说关键的break和contin…

分布式存储故障导致数据库无法启动故障处理---惜分飞

国内xx医院使用了国外医疗行业龙头的pacs系统,由于是一个历史库,存放在分布式存储中,由于存储同时多个节点故障,导致数据库多个文件异常,数据库无法启动,三方维护人员尝试通通过rman归档进行应用日志,结果发现日志有损坏报ORA-00354 ORA-00353,无法记录恢复,希望我们给予支持 M…

AI智能分析高精度烟火算法EasyCVR视频方案助力打造森林防火建设

一、背景 随着夏季的来临,高温、干燥的天气条件使得火灾隐患显著增加,特别是对于广袤的森林地区来说,一旦发生火灾,后果将不堪设想。在这样的背景下,视频汇聚系统EasyCVR视频融合云平台AI智能分析在森林防火中发挥着至…

人脸消费给传统食堂带来的变化

消费的技术基础是脸部识别,脸部识别是基于人的容貌特征信息进行认证的生物特征识别技术,其突出的特征是以非接触方式进行识别,避免个人信息的泄露。 面部识别和指纹识别、掌纹识别、视网膜识别、骨骼识别、心率识别等都是人体生物特征识别技术…

自然资源-城镇开发边界内详细规划编制技术指南解读

自然资源-城镇开发边界内详细规划编制技术指南解读