TNN行业首发Arm 32位 FP16指令加速,理论性能翻倍

2023-10-27

转自:https://cloud.tencent.com/developer/article/1774206

https://www.cnblogs.com/zhangshenghui/p/11825760.html

FP16是半精度浮点格式,相比常用的FP32单精度浮点,数据宽度降低了一半。2016年Arm更新了Armv8.2-A Extension扩展指令集,其中包含FP16半精度浮点运算。Arm NEON向量指令长度为128位,一条FP32向量可完成4个单精度浮点数运算,一条FP16向量可完成8个半精度浮点数运算,使理论峰值性能翻倍。如果该指令用于加速网络推理,相比于FP32预期能达到2倍加速。

1.2 为什么要支持Arm32位FP16指令加速?

智能手机分为Arm32和Arm64位两种架构,其中Arm64占绝大比例,苹果从2013年9月发布iPhone5s后,所有机型全都是Arm64架构。在Arm64架构手机上,App编译为64位可以获得最大的性能,但Arm64架构也支持按照32位编译的APP运行,而Arm32架构无法支持按照64位编译的APP运行。因此出于机型覆盖率以及软件包大小的考虑,当前众多App只会发布32位编译的版本。

经调研,行业开源推理框架如ncnn、MNN等仅支持Arm64位FP16指令加速,这样32位App无法享受FP16指令加速效果。针对这个行业缺失,TNN在架构兼容、模型兼容、代码结构设计等方面率先进行探索,对Arm64位和Arm32架构均实现了FP16指令优化,让64位和32位App都能发挥硬件FP16向量加速的能力。

 

2.1 架构兼容性设计

由于深度学习网络的算子种类繁多,并且随着新模型不断被开发,算子类型也会随之增加,因此,难以一次性为所有层提供FP16加速。我们采用TNN中广泛使用的注册机制,以实现FP16加速的增量开发。实现如下:

①在ArmDevice下维护一个全局的layer_precision_map,将算子类型映射到其支持的数据类型;

②每实现一个FP16加速算子,使用REGISTER_ARM_PRECISION_FP16+LayerType,更新layer_precision_map;

③在运行模型的初始化过程,TNN根据layer_precision_map的信息,为模型中的每一层分发计算精度。仅当算子已支持FP16加速,并且运行平台具备FP16加速硬件时,该层才会使用FP16精度计算。当用户设置的网络精度为PRECISION_HIGH时,可以强制禁用FP16加速。

2.2 模型兼容性设计

部署时模型的算子各种各种,为了获得最大的性能,TNN支持模型按照FP32和FP16混合运行加速。对模型中已实现FP16加速的算子,TNN默认自动按照FP16加速,而对模型中未实现FP16加速的算子,TNN在静态图中自动插入Reformat层转为FP32加速。如下图所示:

 

在TNN的图优化过程中,当发现Pad层不支持FP16加速时(如图a所示),会在其输入和输出分别插入Reformat层。Reformat层负责将FP16和FP32数据格式以及数据排布做相互转换,以支持Pad层单独采用FP32计算,其余层仍采用FP16计算。

如果模型中存在多个相连的层不支持FP16(如图b所示),TNN的图优化机制会避免在这些层之间插入成对的Reformat层,以提高运行效率。

2.3 代码结构设计

为了在32位和64位库中都支持FP16,整体代码结构如下图所示。其主要分为五个部分,通过CMake中不同的配置项,可编译出不同的target。各个部分的主要区别体现在针对不同Arm指令集实现了特定优化。

 

由上图可知,aarch32和aarch64 FP16指令代码独立于其他部分。因为编译FP16指令需要添加特定的编译选项,如果对TNN代码全局添加该选项,会导致编译器将选项应用到所有代码中,然后基于Armv8.2-A架构生成目标文件。

例如在Arm64 Target中,在编译Armv8指令代码时添加该选项,会生成一些Armv8.1或Armv8.2指令集中独有的指令。这些指令若在不支持v8.1和v8.2的Armv8 CPU上运行,会直接导致程序崩溃。因此,为了最大限度地提高兼容性,Armv8.2-A FP16指令代码被单独剥离,单独使用编译选项,避免影响其他部分。

综上所述,TNN库会同时包含两种架构的指令:

  • 64位库:包含Armv8指令和aarch64 Armv8.2-A FP16指令。
  • 32位库:包含Armv7指令和aarch32 Armv8.2-A FP16指令。

2.4 运行时兼容性设计

由上可知,TNN库中包含两种架构的指令。当运行64位或32位库时,若在不支持Armv8.2-A的CPU上执行Armv8.2-A指令,会直接导致程序崩溃,在运行时造成兼容性问题。

针对上述问题,在执行推理之前,TNN会判断当前运行的CPU是否在白名单中、是否支持Armv8.2-A。如果支持,则会运行FP16算子,否则仍然运行FP32算子,避免执行Armv8.2-A FP16指令。具体判断方式如下:

①在IOS和OSX下,通过系统调用sysctlbyname("hw.cpufamily"),获取CPU型号,然后与维护的白名单比较,判断CPU是否支持FP16加速。目前的白名单包括IOS的A11-A14,和OSX的M1。

②在Android和Linux下,通过系统调用getauxval(AT_HWCAP),获取hwcap flag,然后与HWCAP_FPHP和HWCAP_ASIMDHP掩码比较,当FPHP位和ASIMDHP位都为1时,CPU可支持FP16加速。

由于Android的C库在API级别18及更高版本中才支持 getauxval,在低版本的32位Android系统中,该系统调用可能会失败。为了支持aarch32 FP16加速,采用直接解析/proc/cpuinfo的方式,判断CPU是否支持FP16加速。通过/proc/cpuinfo获取处理器的MIDR(Main ID Register),根据该标志可判断处理器厂商和型号,例如Arm的Cortex-A55,海思的Cortex-A76 (HiSilicon)等。然后与维护的白名单比较,最终判断硬件是否支持FP16加速。

 

TNN已对部分算子实现了FP16优化,在64位和32位库中均取得了不错的加速效果,相比于一些开源框架也具备一定的性能优势,如下图中的对比数据所示。

 

 

在A76大核上,TNN的FP32和FP16性能均能保持前列。在A55小核上,Bolt框架针对A55单独做了特殊优化,在性能测试时效果会更好。但实际应用中,由于进程可能会在小核和大核上动态调度,A55特殊优化版本在A76大核上运行的性能较差,所以实际应用的表现不一定会好。TNN采取的是相对折中的实现,在大核和小核上都能取得不错的性能表现。

 

TNN已经对大量的实现细节做了封装,只需要对少量参数进行配置,就可以轻松获得FP16的加速。

链接:https://github.com/Tencent/TNN

点击阅读原文可直接跳转链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TNN行业首发Arm 32位 FP16指令加速,理论性能翻倍 的相关文章

  • 在linux shell中使用ftp命令来实现自动登陆、上传与下载

    前段时间有个需求 需要利用crontab定时往某个FTP上传文件 原以为linux中带的ftp命令只支持交互式的操作 没法在命令行下使用 所以后来打算利用PHP中提供的ftp命令来做 但是很不幸的发现ftp模块不是PHP的标准模块 还需要自
  • 【Linux

    目录 一 概述 二 test 命令 2 1 test 命令 2 2 方括号测试条件 2 3 test 命令和测试条件可以判断的 3 类条件 2 3 1 数值比较 2 3 2 字符串比较 三 复合条件测试 四 if then 的高级特性 五
  • intel性能测试工具VTune的功能和用法介绍

    转自 https blog csdn net WY stutdy article details 79106501 https software intel com en us node 256997 1 VTune介绍 VTune可视化性
  • Linux系统之I/O进程

    Linux系统之I O进程 1 C库和C程序的编译过程 1 1 C库的分类 1 1 1 静态库的概念 1 1 2 制作静态库 1 1 3 动态库的概念 1 1 4 制作动态库 1 2 编译过程 共四步 2 标准I O 2 1 文件类型 2
  • linux驱动开发(四):ioctl()函数

    前文中我们介绍了应用程序通过使用虚拟文件系统VFS提供的接口 来控制字符驱动程序 完成字符驱动设备的open close read write操作 但是如果我们想进行除此以外的其他操作 拓展一些file operations给出的接口中没有
  • SMTP邮件格式、SMTP 协议,SMTP的MIME写法,SMTP发送HTML邮件

    转载 http blog sina com cn s blog 759444350100vx8u html MIME邮件格式 在RFC 2822文档中定义了简单的ASCII编码的Email的邮件格式 然而随着Internet的发展 Emai
  • Linux gdm问题解决解决

    修改 etc inittab 改变runlevel为5 例如 root QRedHat etc cat etc inittab id 5 initdefault 修改GDM的配置文件 etc X11 gdm gdm conf 将 xdmcp
  • ssh免密登录,各种权限设置都无效的解决办法!

    如果失败 有可能是以下原因 1 权限问题 这个还得试试 有可能你的权限真的不对 ssh目录 以及 home 当前用户 需要700权限 参考以下操作调整 sudo chmod 700 ssh sudo chmod 700 home 当前用户
  • Android11 热点设置永不关闭

    Android11 热点设置永不关闭 文章目录 Android11 热点设置永不关闭 一 前言 二 framework设置热点永不超时关闭 三 基于 SoftApManager java 研究超时逻辑 三 总结 1 设置热点不关闭的方法 1
  • linux设置系统时间

    我们一般使用 date s 命令来修改系统时间 比如将系统时间设定成20066年10月19日的命令如下 date s 10 19 2006 将系统时间设定成下午1点12分0秒的命令如下 date s 13 12 00 注意 这里说的是系统时
  • Android数据的四种存储方式SharedPreferences、SQLite、ContenProvider

    作为一个完整的应用程序 数据存储操作是必不可少的 因此 Android系统一共提供了四种数据存储方式 分别是 SharePreference SQLite Content Provider File 由于Android系统中 数据基本都是私
  • linux系统之字符设备驱动——IIC驱动mma8451q

    linux系统之字符设备驱动 IIC子系统驱动mma8451q 1 原理图 2 驱动程序 mma8451q c Author your name Date 2021 02 23 22 16 37 LastEditTime 2021 02 2
  • 理解virt res shr之间的关系 - linux

    转自 https www orchome com 298 想必在linux上写过程序的同学都有分析进程占用多少内存的经历 或者被问到这样的问题 你的程序在运行时占用了多少内存 物理内存 通常我们可以通过top命令查看进程占用了多少内存 这里
  • Linux系统图形界面,字符界面切换快捷键。启动图形界面服务。

    Ctrl Alt F3 启动字符界面 Ctrl Alt F7 启动图形界面 启动图形界面服务 cd etc init d service lightdm restart
  • Linux Top 命令解析

    转自 http www jb51 net LINUXjishu 34604 html TOP是一个动态显示过程 即可以通过用户按键来不断刷新当前状态 如果在前台执行该命令 它将独占前台 直到用户终止该程序为止 比较准确的说 top命令提供了
  • 挂载mount问题“wrong fs type, bad option, bad superblock on ”的解决办法

    重装系统后挂载一般会出现如下问题 problem ivy ivy OptiPlex 380 source sudo mount 192 168 9 18 home deep dev env source mount wrong fs typ
  • android Jar文件的数字签名

    转自 http hubingforever blog 163 com blog static 17104057920118104058241 JAR文件可以用 jarsigner工具或者直接通过 java securityAPI 签名 签名
  • Linux系统制作Ubuntu18.04启动盘

    转自 https blog csdn net xiaoma 2018 article details 85059930 首先进入 Ubuntu 官网下载 Ubuntu18 04 ios 镜像包 下载的镜像包为 ubuntu 18 04 1
  • Windows挂载Linux网络共享文件夹

    Windows挂载Linux网络共享文件夹 创建Linux网络共享文件夹 用共享工具samba Ubuntu安装samba sudo apt install samba 配置Windows访问共享文件夹的账户 smbpasswd a riv
  • Android下自定义的jar库文件编译和调用

    主要为了解决如下问题 项目中使用了Android未公开的API 在Eclipse下会有红叉显示 不同的项目抽出相同部分的代码共用 必需的前提条件 需要有Android源代码 编译的库文件主要是封装未公开API或者共用代码 工程1 Java库

随机推荐

  • Go_方法、方法重写、方法与函数的区别

    方法 方法是绑定在自定义类型上的 常用在结构体上 方法方法不能直接调用 只能通过所绑定s类型的变量来调用 因为方法是和类型做关联的 方法是值拷贝的传递方式 如果希望改变结构体变量的值 需要通过结构体指针实现 方法名首字母大写为公共 小写为私
  • Tomcat的下载及其使用

    目录 一 Tomcat是什么 二 Tomcat的下载安装 1 在搜索框搜索Tomcat 2 下载 3 Tomcat里面的一些具体内容 三 运行Tomcat 1 直接点击脚本运行 2 使用浏览器访问 3 部署页面到Tomcat 一 Tomca
  • Win10如何彻底删除360的办法

    很多用户在购买电脑或者重装系统之后都会给电脑安装360安全卫士 其实360是一款知名的流氓软件 感觉进行了彻底的删除工作 其实还残留了很多 那Win10如何彻底删除360呢 下面小编就来给大家展示一下具体的办法 2022新版Win10 64
  • SQL Part3 --- 聚合操作符

    SQL 聚合操作符 聚合操作符 Aggregate Operators COUNT A SUM A AVG A MAX A MIN A GROUP BY and HAVING 聚合操作符 Aggregate Operators Sailor
  • 在Spring-Boot中进行单元测试

    要进行单元测试 需要引入依赖
  • 关于stl容器的迭代器失效问题

    场景 在项目中使用stl容器的时候 多线程环境下出错 调试很久发现问题是使用容器的时候由于容器扩容导致的线程不安全 还有扩容导致的迭代器失效问题 于是就想着把迭代器失效的问题总结一下 场景重现1 我在项目开发中使用vector时 由于扩容导
  • redis-benchmark工具入门之生成压测数据写入redis

    前言 redis benchmark是Redis自带的基准测试工具 可以用来压测redis目标集群的性能 也可以生成测试数据 方便测试 安装redis benchmark 本文Ubuntu系统 安装工具包 sudo apt get inst
  • 怎样正确查看Linux的内存占用情况

    了个24小时的稳定性测试 探讨了Linux的Mem使用情况 看内存最方便的命令是free m 如 root host free m total used free shared buffers cached Mem 1024 1005 19
  • 100ask_imx6ull视频监控项目-内网穿透(六)

    100ask imx6ull视频监控项目 内网穿透 六 在前面的课程 Ffmpeg和Nginx都运行在开发板上 拉流端只能在同一个局域网内 不能通过局域网外的互联网访问Ngnix 想在任何地方 都可以通过互联网访问Nginx 怎么办 方法1
  • scikit-learn kmeans++

    聚类分析在客户细分中极为重要 有三类比较常见的聚类模型 K mean聚类 层次 系统 聚类 最大期望EM算法 在聚类模型建立过程中 一个比较关键的问题是如何评价聚类结果如何 会用一些指标来评价 原文 http blog csdn net s
  • 【控制工程】单位跃阶响应与传递函数

    一 一阶线性时不变系统的单位阶跃响应 1 单位跃阶 Unit Step 单位阶跃响应是指系统在 单位阶跃信号 的作用下所产生的 零状态响应 作用 可以反应系统的动态特性 所以是分析系统时十分重要和常用的响应类型 注意 单位阶跃函数在t 0这
  • 【数模】TOPSIS法优劣解距离法

    TOPSIS的介绍 利用原始数据的信息 其结果能精确地反映各评价方案之间的差距 层次分析法的局限性 评价的决策层不能太多 否则n很大 判断矩阵和一致矩阵差异可能会很大 平均随机一致性指标RI的表格中n最多是15 TOPSIS步骤 1 将原始
  • 8645 归并排序(非递归算法)

    8645 归并排序 非递归算法 如果你看到和我的贼相似的 那我就是抄的 别骂了 代码实现 include
  • Spring MVC的高级功能(异常处理器,拦截器,文件操作)

    目录 异常处理 拦截器 文件上传和下载 1 异常处理 简单异常处理 自定义异常处理 异常处理注解 简单异常处理器 HandlerExceptionResolver接口 如果希望对Spring MVC中所有异常进行统一处理 可以使用Sprin
  • 卷积层的主要作用_关于卷积的一些基本概念理解(不仅仅是卷积)

    卷积就是相乘再相加 卷积核需要翻转 方便对图像提取特征或者是其他的一些目的 比如边缘检测 除了原图像之外 另一个被用来相乘相加的就被称为是卷积核 同时 卷积核也被称为滤波器 卷积的更加详细生动的解释 https www cnblogs co
  • 百度开源PaddleOCR 超轻量级中文OCR模型,总模型仅8.6M 测试

    版本 https github com PaddlePaddle PaddleOCR git 可以与同样轻量级的ocr识别比较 百度的要好一点 https blog csdn net jy1023408440 article details
  • JAVA--数组元素查找方法

    从头遍历 没有约束条件 数组元素的查找方法 public static int getIndex int arr int key for int i 0 i
  • 如何才能让区块链技术避免成为一个口号?

    区块链是目前互联网上最受热捧的技术 即使是在今年年初数字货币的低迷和ICO被监管部门明确禁止 技术能否落地受到质疑 但是区块链的大火仍在弥漫 现在 这把火已经烧到了很多领域 从金融再到医疗 能源 防伪 溯源 音乐 电影等行业 无不意外的 都
  • 实战Elastic Stack分析K8S应用日志--交付kibana

    Kibana是一个开源的分析和可视化平台 用于和Elasticsearch一起工作 用Kibana来搜索 查看 并和存储在Elasticsearch索引中的数据进行交互 可以轻松地执行高级数据分析 并且以各种图标 表格和地图的形式可视化数据
  • TNN行业首发Arm 32位 FP16指令加速,理论性能翻倍

    转自 https cloud tencent com developer article 1774206 https www cnblogs com zhangshenghui p 11825760 html FP16是半精度浮点格式 相比