[W806捣鼓手记]FPU性能简单测试——2022.05.23

W806 是一款安全 IoT MCU 芯片。芯片集成 32 位 CPU 处理器,内置 UART、GPIO、SPI、SDIO、 I2C、I2S、PSRAM、7816、ADC、LCD、TouchSensor 等数字接口;支持 TEE 安全引擎,支持多种硬件加解密算法,内置 DSP、浮点运算单元与安全引擎,支持代码安全权限设置,内置 1MB Flash 存储器,支持固件加密存储、固件签名、安全调试、安全升级等多项安全措施,保证产品安全特性。适用用于小家电、智能家居、智能玩具、工业控制、医疗监护等广泛的物联网领域。


FPU简介

以下内容摘抄自《玄铁E804用户手册_v04》

浮点单元作为 E804 的可配置硬件单元,旨在提升 E804 面向浮点应用的处理能力。E804 浮点单元提供了一种低成本、高性能的硬件浮点实现。
浮点单元支持 IEEE-754 浮点标准中的单精度浮点运算,实现了 16 个单精度浮点寄存器。在系统软件支持下,E804可实现对双精度浮点运算的支持。

浮点单元的体系结构与编程模型的主要特点如下:

  • 完全兼容 ANSI/IEEE Std 754 浮点标准(系统软件支持下);
  • 仅支持单精度浮点运算;
  • 支持向零舍入、向正无穷舍入、向负无穷舍入和就近舍入四种舍入方式;
  • 支持浮点异常的陷入与非陷入两种处理模式;
  • 支持浮点异常的精确处理;
  • 支持浮点硬件除法与开方。

浮点单元的微体系结构的主要特点如下:

  • 16 个独立的单精度浮点寄存器;
  • 单发射结构,每个周期处理一条浮点算术指令;
  • 支持浮点算术指令的按序发射、按序执行、按序回写;
  • 包含三条独立的执行流水线,分别是浮点 ALU、浮点乘法与浮点除法开方;
  • 优化的执行延时技术,除浮点除法开方指令外,均可在 1-2 个时钟周期执行完毕;
  • 基于运算部件复用的成本优化技术;
  • 基于门控时钟与数据通路隔离的功耗优化技术。

测试项目

基本算法

  • 浮点与浮点的加减乘除
  • 三角函数和反三角函数
  • 开平方
  • e为底的X次幂
  • X的Y次幂

复合算法

  • 100点一阶低通滤波
  • 100点正弦曲线值
  • 32*32像素RGB转灰度

测试方法

分别记录关闭FPU和开启FPU时,10ms定时周期内的算法执行次数,值越高越好。
所有测试统一使用单精度浮点,代码-O3优化,为了尽量减少循环带来的额外开销,手动展开了最里层的循环。

测试结果

基本算法

浮点与浮点的加减乘除

__IO uint32_t cnt = 0;
__IO float a = 1.1f;
__IO float b = 0.123456f;
__IO float c;

while(1)
{
	c = a + b;
	c = a + b;
	c = a + b;
	c = a + b;
	cnt += 4;
}

结果如下,减法、乘法、除法的测试方法和加法是一样的,所以测试代码就不放出来了。

算法关闭FPU(次/10ms)打开FPU(次/10ms)次数比
c = a + b1270831926825.12
c = a - b1111631926828.72
c = a * b1864031926817.13
c = a / b55926941212.41

三角函数和反三角函数

算法关闭FPU(次/10ms)打开FPU(次/10ms)次数比
c = sinf(a)4401406831.97
c = cosf(a)4801562832.56
c = tanf(a)236926839.27
c = asinf(a)6612411126.22
c = acosf(a)6668378605.68
c = atanf(a)336381611.36

开平方

while(1)
{
	c = sqrtf(a);
	c = sqrtf(a);
	c = sqrtf(a);
	c = sqrtf(a);
	cnt += 4;
}
算法关闭FPU(次/10ms)打开FPU(次/10ms)次数比
sqrtf()7364577047.84

e为底的X次幂

while(1)
{
	c = expf(a);
	c = expf(a);
	c = expf(a);
	c = expf(a);
	cnt += 4;
}
算法关闭FPU(次/10ms)打开FPU(次/10ms)次数比
expf()4441440432.44

X的Y次幂

while(1)
{
	c = powf(a, b);
	c = powf(a, b);
	c = powf(a, b);
	c = powf(a, b);
	cnt += 4;
}
算法关闭FPU(次/10ms)打开FPU(次/10ms)次数比
powf()124530842.8

复合算法

100点一阶低通滤波

__IO float t1[100];
__IO float t2;

static inline float first_oder_filter(float new_data)
{
  static float old_data;
  float a = 0.05f;
  old_data = a * new_data + (1.0f - a) * old_data;
  return old_data;
}

int main(void)
{
	SystemClock_Config(CPU_CLK_240M);

	for (uint32_t i = 0; i < 100; i++)
	{
		t1[i] = rand() / (float)(RAND_MAX / 0xffff);
	}
	while (1)
	{
		for (uint32_t i = 0; i < 100; i += 4)
		{
			t2 = first_oder_filter(t1[i]);
			t2 = first_oder_filter(t1[i + 1]);
			t2 = first_oder_filter(t1[i + 2]);
			t2 = first_oder_filter(t1[i + 3]);
		}
		cnt++;
	}

	return 0;
}
关闭FPU(次/10ms)打开FPU(次/10ms)次数比
37194052.43

100点正弦曲线

int main(void)
{
	SystemClock_Config(CPU_CLK_240M);

	/* 正弦曲线公式:y=Asin(ωx+ψ)+k */
	__IO float W = 3.1415926f / 50.f;
	__IO float A = 100.0f;
	__IO float k = 50.0f;
	__IO float offset = 6.0f;
	__IO float wave;
	__IO float x[100] = { 0.0f };
	
	float temp = 0.0f;
	for (uint32_t i = 0; i < 100; i++)
	{
		x[i] = temp + 0.05f;
	}

	while (1)
	{
		for (uint32_t i = 0; i < 100; i += 4)
		{
			wave = A * sinf(W * x[i] + offset) + k;
			wave = A * sinf(W * x[i + 1] + offset) + k;
			wave = A * sinf(W * x[i + 2] + offset) + k;
			wave = A * sinf(W * x[i + 3] + offset) + k;
		}
		cnt++;
	}

	return 0;
}
关闭FPU(次/10ms)打开FPU(次/10ms)次数比
411629.0

32*32像素RGB转灰度

int main(void)
{
	SystemClock_Config(CPU_CLK_240M);

	__IO uint32_t cnt = 0;
	__IO uint8_t color_r[32][32];
	__IO uint8_t color_g[32][32];
	__IO uint8_t color_b[32][32];
	__IO uint8_t color_gray[32][32];

	for (uint32_t i = 0; i < 32; i++)
	{
		for (uint32_t j = 0; j < 32; j++)
		{
			color_r[i][j] = rand() % 0xff;
			color_g[i][j] = rand() % 0xff;
			color_b[i][j] = rand() % 0xff;
		}
	}

	while (1)
	{
		for (uint32_t i = 0; i < 32; i++)
		{
			for (uint32_t j = 0; j < 32; j += 4)
			{
				color_gray[i][j] = color_r[i][j] * 0.299f + color_g[i][j] * 0.587f + color_b[i][j] * 0.114f;
				color_gray[i][j + 1] = color_r[i][j + 1] * 0.299f + color_g[i][j + 1] * 0.587f + color_b[i][j + 1] * 0.114f;
				color_gray[i][j + 2] = color_r[i][j + 2] * 0.299f + color_g[i][j + 2] * 0.587f + color_b[i][j + 2] * 0.114f;
				color_gray[i][j + 3] = color_r[i][j + 3] * 0.299f + color_g[i][j + 3] * 0.587f + color_b[i][j + 3] * 0.114f;
			}
		}
		cnt++;
	}

	return 0;
}
关闭FPU(次/10ms)打开FPU(次/10ms)次数比
26130.5

总结

通过以上测试结果可以发现,W806的XT804内核在没有FPU时的浮点数计算能力是非常弱的,而FPU的加入可以大幅提高内核对于单精度浮点的计算能力,不管是基础算法还是复合算法,几乎都是几十倍的提升。W806的工程是默认开启FPU的,直接用就好。

参考资料

  1. 《W806 MCU 芯片规格书V2.0》
  2. 《玄铁E804用户手册_v04》
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值