`
xiaoer_1982
  • 浏览: 1871181 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Vdsp(bf561)中的浮点运算(6):float加减运算

阅读更多

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

本文适用于

ADSP-BF561

Visual DSP++ 5.0 (update 6)

Vdsp dual processor simulate

欢迎转载,但请保留作者信息

一直以为float加减运算很简单,无非就是将之转换为__float32_add__float32_sub这两个函数调用而已,然后用软件模拟进行加减运算。但真的如此简单吗?当一些让人不太舒服的条件出现的时候,还是如此吗?

1.1 Vdspfloat加减运算的处理

vdsp下,可以很简单地用:

float add(float x, float y)

{

float r = x + y;

return r;

}

float sub(float x, float y)

{

float r = x - y;

return r;

}

来完成浮点加减运算,编译器自动将里面的加法操作转换为___float32_add的函数调用,而将减法操作转换为___float32_sub的函数调用,这两个函数的调用实现在libdsp/fpadd.asm中:

___float32_sub:

BITTGL(R1,31); // Flip sign bit of Y, fall through to add

.align 2;

___float32_add:

从这几行代码可以看出减法无非就是把减数改变符号再用加法实现而已。

1.2 y0

__float32_add的代码:

// check for addition of 0.0

R3 = R1 << 1; // Remove sign

CC = R3; // If Y=0, return X

IF !CC JUMP .return_x_nopop;

………..

.return_x_nopop:

#if CHECKING_FOR_NEGZERO_RES

R1 = R0 << 1;

CC = R1;

IF !CC R0 = R1; // convert any -0.0 to 0.0

#endif

RTS;

直接返回x的值,此时的操作需要的CYCLE数为25

1.3 x0

R2 = R0 << 1; // Remove sign

CC = R2; // If X=0, return Y

IF !CC JUMP .return_y_nopop;

……….

.return_y_nopop:

R0 = R1;

RTS;

直接返回y的值,此时的操作需要的CYCLE数为26

1.4 xNAN或者INF

// Check for all exponent bits set, indicating a NaN or inf operand

R4 = R2 >> 24; // Extract X exponent

R5 = R3 >> 24; // Extract Y exponent

R6 = MAXBIASEXP+1;

CC = R4 == R6;

// Handle identities where X is NaN or inf.

IF CC JUMP .handle_nan_inf_x;

…………….

.handle_nan_inf_x:

// If x == inf, y a number ,return x

// If y == inf, and x&y have same sign, return x; (x may be NaN)

// else return NaN

CC = R5 < R6; // If exp Y < MAXBIASEXP+1

R2 = R0 << 9; // and X is inf

CC &= AZ;

IF CC JUMP .return_x_not0; // Return inf

CC = AZ; // If X is inf

R2 = R1 << 9; // then we can deduce all Y exponent bits set

CC &= AZ; // so Y is inf if no significand bits set

R2 = R0 ^ R1; // and Y is of the same sign

R2 >>= 31;

CC &= AZ;

R1 = -1; // R1 = default NaN

IF !CC R0 = R1;

.return_x_not0:

(R7:4) = [SP++];

RTS;

很多判断条件:

l x == infy是一个正常数

返回x

add(inf, 4)的结果就是inf

add(-inf, 4)的结果就是-inf

此时的操作需要的CYCLE数为50

l y == infxy同号

返回x

add(inf, inf)的结果为inf

add(-inf, -inf)的结果为-inf

add(inf, -inf)的结果为nan

add(nan, inf)的结果为nan

add(nan, -inf)的结果为nan

此时的操作需要的CYCLE数为50

l 其它

返回nan

此时的操作需要的CYCLE数为50

1.5 x为正常数且ynan或者inf

// If X is a number, but Y is NaN or inf, return Y.

CC = R5 == R6;

IF CC JUMP .return_y;

………….

.return_y: // no need for -0.0 return check for this case

(R7:4) = [SP++];

.return_y_nopop:

R0 = R1;

RTS;

直接返回y的值,如

add(4, inf)的值为inf

add(4, -inf)的值为-inf

add(4, nan)的值为nan

此时的操作需要的CYCLE数为40

1.6 当指数差大于24

fpadd.asm里面这样解释这个条件:

// Extract and compare the two exponents. Since there are

// 23 bits of mantissa, if the difference between exponents (D)

// is greater than 24, the operand with the smaller exponent

// is too insignificant to affect the other. If the difference

// is exactly, the 24th (hidden) bit will be shifted into the

// R position for rounding, and so can still affect the result.

// (R is the most significant bit of the remainder, which is

// all the bits shifted off when adjusting exponents to match)

由于float里面的尾数部分只有23位,因此当两个数的指数差大于24时可以直接忽略这个比较小的数,转换为十进制的差别就是1.6777216e7

比如add(1<<24, 1)的结果为1<<24

此时的CYCLE136

1.7 当小数加上大数

__float32_add的代码可以发现,当加法操作的第一个操作数较小时它会交换两个操作数的位置:

// If the exponents are different, then we arrange the

// operands so that X is the larger, and we're adding

// a less-significant number to it. Because the exponents

// are biased (the eeeeeeee bits are the true exponent,

// with +127 added), we remove the sign bits of X and Y,

// and then compare directly.

CC = R3 <= R2 (IU); // compare X and Y values (exp and mant)

IF CC JUMP .no_swap; // okay if Y exp is smallest

// Y exp is biggest. Swap.

P1 = R5; // default exp of result

R5 = R0; // swap x and y

R0 = R1;

R1 = R5;

R4 = -R4; // negate D.

.no_swap:

………………

初看这个注释,得到的印象是如果第一个操作数大于第二个操作数,那么应该可以节省几个CYCLE,在大量运算时就可以很可观地节省很多时间。

但实际测试的结果却是:

add(10000.0, 10.0)需要的CYCLE136

add(10.0, 10000.0)需要的CYCLE则为132

为什么???

VDSP下跟踪进去,发现了一个很有意思的现象,当需要进行交换的时候(CC=1),这个时候表示PC的光标会指向

P1 = R5; // default exp of result

这行语句,而不是直接跳转到.no_swap。但是光标的颜色由正常的黄色变为灰色,寄存器的值也不会改变。

于是乎想起了pipeline,在pipeline viewer里面可以看到pipeline进行了一个很明显的清空操作,这样造成了从

IF CC JUMP .no_swap; // okay if Y exp is smallest

.no_swap跳转完成整整花了10CYCLE

当需要交换的时候,由于pipeline没有中断,从

IF CC JUMP .no_swap; // okay if Y exp is smallest

执行到.no_swap只花了6CYCLE

第一次这么近距离地感受到了JUMP对效率的伤害!!也明白了uclinux内核里面likelyunlikely对效率的贡献!!

1.8 溢出

当两个数相加超过float的表示范围,将返回inf或者-inf

比如:

add(FLT_MAX, FLT_MAX)的结果就是inf

2 参考资料

Vdsp(bf561)中的浮点运算(5):float类型表示总结(2009-8-12)

Vdsp(bf561)中的浮点运算(4):FLT_MAX(2009-8-12)

Vdsp(bf561)中的浮点运算(3):FLT_MIN(2008-12-19)

Vdsp(bf561)中的浮点运算(2):float的疑问(2008-12-18)

Vdsp(bf561)中的浮点运算(1):文档的说法(2008-12-16)

分享到:
评论

相关推荐

    u-boot-1.1.6 for vdsp(bf561)

    2. **存储器支持**:BF561支持NandFlash和NorFlash两种非易失性存储器。u-boot需要包含对应的驱动,以便能够读取和写入这些存储介质。这些驱动通常位于`drivers`目录下。 3. **串口通信**:该版本的u-boot支持通过...

    uclinux-2008r1到vdsp5(bf561)的移植记录_v0.1

    ### uclinux-2008r1-rc8到VDSP5 (bf561)的移植知识点 #### 1. 前言 - **目标**:本移植项目旨在将uclinux-2008r1-rc8内核从bf561处理器移植到VDSP5平台上。 - **原则**:遵循uCLinux移植的基本原则,确保移植后的...

    u-boot-1.1.6-2008R1到vdsp5(bf561)的移植记录_v0.1

    ### u-boot-1.1.6-2008R1到VDSP5 (bf561) 的移植记录 #### 1.1 #if 在进行u-boot移植的过程中,遇到的第一个问题是关于`#if`预处理器指令的问题。具体来说,在`u-boot-1.1.6-2008R1\include\configs\bf561-ezkit.h`...

    编译器VDSP_v0.1

    #### 五、VDSP 4.5(BF561)中的CPLB - **LDF配置**: 配置LDF文件以支持CPLB。 - **缓存空间定义**: 定义要缓存的空间。 - ***_basiccrt.s**: 更新`*_basiccrt.s`文件以支持CPLB操作。 - **错误处理**: 处理可能出现...

    uboot_bf537_vdsp

    在描述中提到,UBOOT_BF537在这个环境下被编译,这表明用户可能遇到了与VDSP++工具链兼容性或者配置相关的问题。 然而,"这个文件有bug"指出UBOOT_BF537在原始状态下可能存在错误或缺陷,这可能涉及到代码逻辑、...

    uboot_bf537_VDSP++5.0

    《uboot_bf537_VDSP++5.0:嵌入式开发的关键组件与实践》 uboot_bf537_VDSP++5.0是针对ADI公司的Blackfin(BF537)处理器设计的一个特定版本的U-Boot引导加载程序。U-Boot是一款广泛应用在嵌入式系统的开源启动加载...

    vdsp查表法

    查表法的基本思想是预先计算一系列函数值并存储在一个数组中,当需要计算某个函数值时,直接从表中查找即可,避免了复杂的数学运算,从而大大提高了计算速度。 #### 三、vdsp中的C语言编程实践 本案例展示了如何在...

    uboot_bf537_VDSP5.0++

    这是在VDSP5.0++下面编译成功的uboot,支持的命令 base - print or set address offset bootm - boot application image from memory cmp - memory compare cp - memory copy crc32 - checksum calculation erase -...

    u-boot-1.1.6-2008R1-vdsp

    5. **编译与烧录**:配置交叉编译工具链,编译生成适合VDSP架构的u-boot二进制文件,然后通过JTAG或串口等手段将其烧录到BF561的存储器中。 6. **测试与调试**:运行u-boot并进行功能测试,如命令行交互、加载内核...

    如何在VDSP下生成和调用DSP库

    ### 如何在VDSP下生成和调用DSP库 #### 一、生成DSP库(*.dlb) 在本文中,我们将详细介绍如何在VisualDSP++环境下创建一个基于C语言的DSP库文件(*.dlb)。这个过程对于Blackfin处理器特别适用,同时也适用于其他ADI...

    Intro_to_VDSP_transcript

    **视觉数字信号处理(VDSP)简介** Visual DSP++ 是一款强大的开发环境,专为数字信号处理(DSP)应用设计,特别是在嵌入式系统中。它由 Analog Devices 公司提供,结合了图形化界面与高效的编译工具,使得开发者...

    VDSP软件说明

    VDSP软件说明。对于visual dsp++软件的介绍,以及如何创建工程等的介绍

    rootfs for uclinux

    本文将深入探讨与uclinux-2.6(bf561)版本配合使用的根文件系统(rootfs)及其核心知识点,以及如何将ext2文件系统集成到VDSP(BF561)处理器中。 首先,根文件系统(rootfs)是Linux系统启动时必须的文件集合,它包含了...

    uclinux-2.6 for vdsp4.5

    这是将uclinux-2.6 for bf561的内核移植到Visual DSP 4.5下的工程文件。由于csdn空间限制,删除了Documentation及doj,dlb等中间文件或者无关的内容,请先在http://blackfin.uclinux.org/下载2.6.19.3-ADI-2007R1.1-...

    BDMA.zip_BDMA_VDSP_dma_字节内存

    标题中的“BDMA.zip_BDMA_VDSP_dma_字节内存”揭示了我们即将讨论的核心主题:BDMA(Block Direct Memory Access)技术,它与VDSP(Vector Digital Signal Processor)相关,涉及DMA(Direct Memory Access)操作...

    uboot1.60429.rar_uboot bf561

    本源码是uboot在bf537芯片上的移植,它是在vdsp++5.0环境下编译的,支持uboot绝大部分常用的命令,方便剪裁

    Vdsp LDF文件格式详解

    ### ADI Blackfin 处理器 Vdsp LDF 文件格式详解 #### 一、概述 在ADI (Analog Devices Inc.) 的Blackfin系列处理器中,`.ldf`(Linker Description File)是一种非常重要的文件类型,它主要用于描述链接器如何...

    Armv8-A Instruction Set Architecture_armv8指令集_ARMv8_源码.zip

    - **浮点运算**:浮点运算通过Advanced SIMD(SIMD即单指令多数据)进行,支持单精度和双精度浮点运算,适合多媒体处理和科学计算。 3. **寄存器**: - **通用寄存器**:AArch64拥有64个64位通用寄存器(X0-X31)...

    idma.zip_VDSP++5.0百度云_pleasantb4s

    《IDMA.zip_VDSP++5.0百度云_pleasantb4s:深入解析VDSP++5.0在嵌入式系统开发中的应用》 在嵌入式系统开发领域,高性能数字信号处理(DSP)技术扮演着至关重要的角色。本文将深入探讨IDMA.zip文件中的主要内容——...

    C++信号的反褶运算

    在计算机科学领域,特别是在信号处理和数字信号处理中,"信号的反褶运算"是一个关键的概念,它在理解和分析各种信号特性时起着至关重要的作用。C++作为一门强大的编程语言,可以用来实现这种运算。在VC(Visual C++...

Global site tag (gtag.js) - Google Analytics