定点运算和浮点运算_C2000浮点运算注意事项——CPU和CLA的差异及误差处理技巧...

C28x+FPU架构的C2000微处理器在原有的C28x定点CPU的基础上加入了一些寄存器和指令,来支持IEEE 单精度浮点数的运算。对于在定点微处理器上编写的程序,浮点C2000也完全兼容,不需要对程序做出改动。浮点处理器相对于定点处理器有如下好处:

  1. 编程更简单

  2. 性能更优,比如除法,开方,FFT和IIR滤波等算法运算效率更高。

  3. 程序鲁棒性更强。

一、IEEE754格式的浮点数

C28x+FPU的单精度浮点数遵循IEEE754格式。它包括:

  • 1位符号位:0表示正数,1表示负数。

  • 8位阶码

  • 23位尾数

31

30                                                                                    23

22                                                  0

符号位

阶码

尾数

表1:IEEE单精度浮点数

符号位S

阶码E

尾数M

0

0

0

正0

1

0

0

负0

0或1

0

非0

非规格化数(1)

0

1-254

0x00000-0x7FFFF

正常范围正数(2)

1

1-254

0x00000-0x7FFFF

正常范围负数(2)

0

255

0

正无穷大

1

255

0

负无穷大

0或1

255

非0

非数值(NaN)

(1)非规格化数值非常小,计算公式为(-1)sx2(E-126)x0.M

(2)正常范围数值计算公式为(-1)sx2(E-127)x1.M

正常范围数值落在± ~1.7 x 10 -38 to ± ~3.4 x 10 +38范围内。从表1可以看出,IEEE754标准包括:

  • 标准数据格式和特殊值,比如非数值(NaN)和无穷大

  • 标准舍入模式和浮点运算

  • 多平台支持,包括德州仪器C67x系列芯片。

C2000对该标准作了一些简化:

  • 状态标志位和比较运算不区分正0和负0

  • 非规格化数值被认为是0

  • 对非数值(NaN)处理方式和无穷大一样。

IEEE754标准有5种舍入模式,C28x+FPU只支持其中两种:

--截断:小数位不管大小全部舍去

--就近舍入向偶舍入:这种模式下如果小数位小于5就舍去,大于5就进位,如果小数位为5,则舍入到最近的偶数。

表2展示了不同的舍入模式对数据的影响。C28x+FPU编译器默认将微处理器配置为就近舍入向偶舍入模式[1]。

表2:不同舍入模式示例

模式 / 实际值

+11.5

+12.5

−11.5

−12.5

就近舍入向偶舍入

+12.0

+12.0

−12.0

−12.0

就近舍入远离0舍入

+12.0

+13.0

−12.0

−13.0

截断

+11.0

+12.0

−11.0

−12.0

向上舍入

+12.0

+13.0

−11.0

−12.0

向下舍入

+11.0

+12.0

−12.0

−13.0

二、浮点C2000芯片运算技巧和注意点

浮点数的精度由尾数位决定,绝大多数的数在用浮点数表示时都会有误差,这些误差很小,多数情况下可以忽略,但是在经过多次计算后这个误差可能会大到无法接受。

下面用实例来进行说明,下面一段代码定义float类型变量,分别在TI最新的Delfino芯片F28379D的CPU1和CLA1上,将11.7加20001次。

float CLATMPDATA=0;

int index=20001;

   while(index--)

   {

       CLATMPDATA=CLATMPDATA+11.7;

}

得到如下结果:

6e0627720cf4216814cbe8e2b0797058.png

其中CLATMPDATA1是在CLA中将11.7加20001次得到的结果,CLATMPDATA2是在CPU中将11.7加20001次得到的结果。可以看出两者所得到的结果不同,并且都和正确结果234011.7有较大差距。

  1. 为何CPU和CLA计算结果不同?

CPU和CLA运算结果的不同是由于其对浮点数的舍入模式的不同造成的,前文已经说过,C28x+FPU 编译器默认将CPU配置为就近舍入向偶舍入模式。而CLA不同,CLA默认为截断舍入模式[2]。在CLA的代码中,我们可以通过增加下述代码:

__asm(" MSETFLG RNDF32=1");//1为就近舍入向偶舍入,0为截断舍入

将CLA的舍入模式更改为就近舍入向偶舍入模式,然后再运行代码,可以得到和CPU同样的结果。

 7685a7e67965c16b2f46d3c12a902f15.png

        2. 为何CPU和CLA计算结果都有较大误差?如何解决?

11.7在用IEEE754格式的浮点数表示时为0x413b3333,其对应的实际值为11.69999980926513671875,可以看出误差很小,但是经过多次累加多次舍入后得到的结果误差较大,对此,我们可以将CLATMPDATA定义为long double型变量(64位),再次运行相同的代码,可以得到如下结果,可以看到误差很小可以忽略。

1932bffacc7723ccdf784d2a2a8cb14d.png

需要指出的是,现有的C28x CPU只支持单精度(32位)的硬件浮点运算,对于64位双精度浮点数的运算都是通过软件实现的,所以其运算速率会慢很多。另外CLA不支持64位数。

在这个实例中,我们可以分别观察float类型变量和long double类型变量的汇编代码如下:

C code: CLATMPDATA2=CLATMPDATA2+11.7;

如果CLATMPDATA2是float型变量,则相应的汇编代码为:

00c08d:   E80209D8    MOVIZ        R0, #0x413b                                1cycle

00c08f:   E2AF0112    MOV32        R1H, @0x12, UNCF  1cycle

00c091:   E8099998    MOVXI        R0H, #0x3333                              1cycle

00c093:   E7100040    ADDF32       R0H, R0H, R1H                            2cycle

00c095:   7700        NOP                                                           1cycle

00c096:   E2030012    MOV32        @0x12, R0H                                1cycle

如果CLATMPDATA2是long double型变量,则相应的汇编代码为:

00c08b:   7680005A    MOVL         XAR6, #0x00005a      1cycle

00c08d:   8F00005A    MOVL         XAR4, #0x00005a      1cycle

00c08f:   8F40C26A    MOVL         XAR5, #0x00c26a       1cycle

00c091:   FF69        SPM          #0                                            1cycle

00c092:   7640C0C9    LCR          FD$$ADD                          4cycle(跳转耗时)

+25cycle(FD$$ADD函数内部需要25cycle)

可以看出CPU对float类型数执行一次加法耗时7个cycle,对long double类型数执行一次加法耗时33个cycle。

三、结论

1. C2000的CPU和CLA默认的舍入模式不同,在计算浮点数时可能会得到不同的结果,但是我们可以通过代码改变其舍入模式得到相同的结果。

2. 单精度浮点数经过多次计算后可能会有较大误差,可以通过将变量定义为64位long double型解决精度问题。

3. C28x CPU只支持单精度(32位)的硬件浮点运算,对于64位双精度浮点数的运算都是通过软件实现的,所以其运算速率会慢很多。在下一代的C2000产品中我们会实现对64位双精度浮点数运算的硬件支持。

References

[1]. TMS320C28x FPU Primer (SPRAAN9A)

[2]. TMS320F2837xD Dual-Core Delfino Microcontrollers Technical Reference Manual (SPRUHM8F)

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

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

相关文章

python模拟登录吃鸡_Python高级爬虫开发,高难度JS解密教程,绝地求生模拟登陆!...

前言这篇文章因为涉及到JS解密部分,所以难度比较高,Python基础比较薄弱的同学可以来看看思路。开始进入到该网站后我们可以看到如下界面,今天要做的内容就是模拟登陆那么咱们首先抓到登陆的包看看:登陆的同时总共发送了两次post请…

imread函数 matlab_地理人,你会用Matlab吗?

​Matlab 读取不同格式数据作为一个地信的小白,本科就学会了一个ArcGIS。虽然Matlab, C, Java, C, C# 等的编程课上了一大堆,但是考完试就完全忘了,妥妥的一个代码小白,当初连如何切换当前目录都不会……读研后,发现Ma…

jquery li ul 伪分页_求教关于Jquery的ul li的分页,该怎么处理

求教关于Jquery的ul li的分页ul 下有若干个li 3个为1个分页 1个input按钮点击显示后3个 另一个显示前3个 求大神这个怎么做分享到:更多------解决方案--------------------html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org…

url过滤怎么解除_腾讯面试官是这样来问布隆过滤器的?

作者:张振伟来源:https://zhangzw.com/20190521.html假设遇到这样一个问题:一个网站有 20 亿 url 存在一个黑名单中,这个黑名单要怎么存?若此时随便输入一个 url,你如何快速判断该 url 是否在这个黑名单中&…

python dataframe遍历_对Python中DataFrame按照行遍历的方法

对Python中DataFrame按照行遍历的方法在做分类模型时候,需要在DataFrame中按照行获取数据以便于进行训练和测试。import pandas as pddict[[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8],[4,5,6,7,8,9],[5,6,7,8,9,10]]datapd.DataFrame(dict)print(data)for indexs i…

mysql数值比中文检索快_MySQL 千万 级数据量根据(索引)优化 查询 速度

一、索引的作用索引通俗来讲就相当于书的目录,当我们根据条件查询的时候,没有索引,便需要全表扫描,数据量少还可以,一旦数据量超过百万甚至千万,一条查询sql执行往往需要几十秒甚至更多,5秒以上…

python enumerate函数_Python中enumerate函数用法详解

enumerate函数用于遍历序列中的元素以及它们的下标,多用于在for循环中得到计数,enumerate参数为可遍历的变量,如 字符串,列表等一般情况下对一个列表或数组既要遍历索引又要遍历元素时,会这样写:for i in range (0,len(list)):pri…

mysql5.7.24 安装步骤_MySQL5.7.24解压版安装步骤

网上安装MySQL数据库的教程有.msi格式包安装和.zip格式解压安装,zip安装我个人感觉安装方式纯净又能学习更多知识,因此我更倾向于zip安装。一、下载并解压前往MySQL官网下载5.7.24版本https://dev.mysql.com/downloads/下拉移动看见select Version 选择m…

python在工作中怎么用_如何用python在工作中“偷懒”

原标题:如何用python在工作中“偷懒”“偷懒还能干完活,才是本事 ”有些朋友在工作中会有这样的困惑:明明我从早忙到晚,为什么得到的评价还不高?要知道,企业对一个员工的评价是出于“ 产出”而非“ 付出”。…

mysql utf8mb4 造成慢_mysql使用utf8mb4经验吐血总结

1. utf8 与 utf8mb4 异同1234The character set named utf8 uses a maximum of three bytes per character and contains only BMP characters. The utf8mb4 character set uses a maximum of four bytes per character supports supplementary characters:- For a BMP charact…

java移动接口发短信_Java面试零碎知识点

1.Java文件经过JVM编译成字节码文件,即.class文件,将字节码文件在不同的操作系统中运行时,操作系统再将字节码文件编译成机器码文件。这就是Java跨平台2.首先明确一点,java 的 GC 回收是完全自动的,没有提供相关 api 手…

如何安装mysql5.7.21_Linux 安装MySql 5.7.21 操作步骤

一:到mysql官网下载最新的mysql包 mysql-5.7.21-linux-glibc2.12-x86_64二:在linux /usr/local/中解压mysql压缩包 改名为mysqlcd /usr/local/tar -xzvf mysql压缩包名三:创建用户组mysql,创建用户mysql并将其添加到用户组mysql中…

java重定向代码_Java程序员经典面试题集大全 (三十四)

341. Servlet API中forward() 与redirect()的区别?答:为实现程序的模块化,就需要保证在不同的Servlet之间可以相互跳转,而Servlet中主要有两种实现跳转的方式:FORWARD方式与redirect方式。 Forward() : 是服务器内部的…

mysql用户阻塞数_MySQL实例阻塞分析一例(线程statistics状态)

本文用实例来分析MySQL阻塞—线程statistics状态。一、 现象某日下午下班后低峰期,现网MySQL一个库突然报出大量慢sql,状态是 statistics,但是过后拿这些sql去执行的时候,实际很快。处于 statistics 状态的线程有个特征&#xff1…

无法获取未定义或 null 引用的属性“text”_【CSS】是时候开始用 CSS 自定义属性了...

自定义属性(有时候也被称作CSS变量或者级联变量)是由CSS作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如:--main-color: black;),由var() 函数来获取值(比如:color: var(--main-color);)复杂的网站都…

斐波那契数列不用数组_兔子数列——斐波那契数列

相信人们都对斐波那契数列有或多或少的了解,如果没有,那你一定听过黄金分割比或是见过下面这种图片:斐波那契生活在十三世纪的意大利,原名列奥纳多皮萨诺(Leonardo Pisano),他出生在意大利那个后来因为伽里略做过自由落…

sqlserver服务启动失败_条码打印软件连接SQL数据库出现TCP连接失败解决办法

小编今天用条码打印软件连接SQL 数据库遇到了一个问题:通过端口1433连接到主机localhost的TCP/IP连接失败。错误:“Connection refused:connect。请验证连接属性。确保SQL Server的实例正在主机上运行,且在此端口接收TCP/IP连接&a…

python怎么播放mp3_python上播放mp3歌曲

试试这个。它过于简单但可能不是最好的方法。from pygame import mixer # Load the required librarymixer.init()mixer.music.load(e:/LOCAL/Betrayer/Metalik Klinik1-Anak Sekolah.mp3)mixer.music.play()请注意,支持MP3pip install pygame第二种方法试一试使用p…

python语言发明者 google_谷歌的语言何以战胜Python?50%的人都应该立即学习Golang...

全文共2623字,预计学习时长9分钟图源:dailybtc很多软件工程师视Python为最喜爱的语言之一,工作生活都和它死死绑定在一起。但Google, Uber, Dropbox, Soundcloud, Slack, 和Medium的软件工程师并不是这样。长期以来,顶级企业的程序…

python基础文档_python基本文件操作

python文件操作python的文件操作相对于java复杂的IO流简单了好多,只要关心文件的读和写就行了基本的文件操作要注意的是,当不存在某路径的文件时,w,a模式会自动新建此文件夹,当读模式,文件不存在&#xff0…