浮点运算的硬件加速

1. 背景

随着人工智能和神经网络的发展,浮点运算的占比越来越大,而浮点运算本身又比较耗时,所以,对大批量数据进行浮点运算时常要耗费数月甚至数年的时间,如:神经网络模型的训练与应用。

2. 硬件加速

浮点运算基础版本使用的是数学协处理器FPU,其拥有8个80位的数据寄存器,所有的浮点运算都是在这8个寄存器上进行的。每个寄存器可以存放一个数据,而且部分寄存器拥有特殊用途,所以,FPU中无法进行运算加速。

后续出现的SSE在一定程度上提高了浮点运算速度。SSE开始支持128位的寄存器,每次可以存放4个单精度浮点数,因而可以一次处理4个同种类的运算。假设FPU要对1000组数据进行加法运算,需要执行1000次的加法指令;而用SSE的128位寄存器进行运算,最少只需执行250次的加法指令即可完成。

再后来出现的AVX以及64位环境下可用的AVX-512进一步扩大了寄存器的尺寸,AVX使用8个256位的寄存器,AVX-512使用8个512位的寄存器。若用AVX-512进行浮点加速,一次可以对16组单精度浮点数进行运算,沿用上例,1000组数据的加法用AVX-512执行的话,最少只需执行62.5次的加法指令即可完成,相对于FPU来说,运算时间减少了93.75%。

后续出现了不少其它的加速方式和配套硬件,典型的是现如今广泛使用的GPU和CUDA编程,其在神经网络模型训练过程中得到了广泛的使用。

3. 分析与总结

从上述讨论中可以看到,对于批量数据的单次同种运算,可以节省很大比例的运算时间。但是,在实际程序运行过程中进行统计和对比发现,加速效果远远达不到预期,甚至在少量环境下还会产生恶化,优化后的程序运行需要消耗更多的时间。

从任务总体过程来看,数据需要不停地在内存与寄存器之间进行传递,这部分操作消耗了大量的时间,甚至远远超过数据在寄存器中执行所消耗的时间,而这部分时间损耗未能得到优化。

这种问题尤其在神经网络这种连续多个运算级联的情形下会产生较大的影响。假设要对1000组数据先进行加法运算,在对运算结果求sin,最后对正弦结果做二值分类。硬件加速后的执行过程是:加载一批数据到寄存器-->加法运算-->把该批结果写回内存-->加载下一批数据到寄存器-->加法运算-->......-->加载一批和值到寄存器-->sin-->把该批结果写回内存-->加载下一批和值到寄存器-->sin-->......-->加载一批sin值到寄存器-->比较分类-->把该批分类结果写回内存-->加载下一批sin值到寄存器-->比较分类......可以看到,在这个过程中不断地重复着读内存、写内存,这不仅消耗大量时间,还打断了流程。如果不用硬件加速的话,可能会是这样的情形:读第一组数据到寄存器-->加法运算-->sin-->比较分类-->把结果写回内存-->读下一组数据到寄存器-->......孰优孰劣尚难评判

综上所述,对于浮点运算的加速,不能简单提高单次数据吞吐量,尤其是对于模型训练这种存在大量异种运算的任务,比硬件本身更重要的是优化算法本身,包括优化模型、计算方法、计算流程等。当然了,对于简单的浮点运算,提高单次吞吐量的硬件加速就能达成预期,譬如对于一大批数据仅执行一两次的同种运算。

在IAR Embedded Workbench中启用和优化硬件FPU(浮点运算单元)的配置,通常涉及以下几个方面:编译器设置、FPU模式选择、优化选项以及浮点运算库的使用。这些配置可以显著提升嵌入式系统中浮点运算的性能和效率。 ### 编译器设置与FPU支持 在IAR中,启用硬件FPU支持的关键在于选择正确的目标架构和FPU模式。例如,在ARM Cortex-M系列中,如果芯片支持FPU(如Cortex-M4或Cortex-M7),则需要在项目选项中指定FPU的存在并选择适当的FPU类型(如`--fpu=VFPv4`或`--fpu=FPv5`)[^1]。 在IAR Embedded Workbench中,可以通过以下路径进行设置: - 打开项目选项(Project → Options) - 在“General Options”下选择目标设备 - 在“C/C++ Compiler → Language → Floating Point”中选择“Hardware”以启用FPU支持 ### 优化选项 IAR编译器提供多种优化级别,包括针对速度(`-Ospeed`)和大小(`-Osize`)的优化。为了更好地利用FPU进行浮点运算,推荐使用速度优化[^1]。此外,还可以启用特定的浮点优化选项,如: - `-Ohf`:启用浮点优化,包括使用FPU指令 - `-Ohs`:启用软件浮点优化(在没有FPU的情况下使用) ### 浮点运算库 IAR提供了高效的数学库,例如`math.h`中的函数。为了充分利用FPU,应确保链接器使用了硬件加速的数学库版本。可以通过以下方式指定: - 在链接器选项中添加`--use_hw_div`和`--use_hw_sqrt`以启用硬件除法和平方根运算[^1] ### 示例代码 以下是一个简单的示例,展示如何在代码中使用浮点运算,并确保编译器使用FPU进行优化: ```c #include <stdio.h> #include <math.h> int main(void) { float a = 3.1415926535f; float b = 2.0f; float result; result = sqrtf(a / b); // 使用FPU进行平方根和除法运算 printf("Result: %f\n", result); return 0; } ``` 在这个示例中,`sqrtf`函数将利用FPU进行高效的平方根计算。 ### 调试与性能分析 为了验证FPU是否被正确启用并优化,可以使用IAR的调试工具和性能分析器。通过查看生成的汇编代码,确认是否使用了FPU指令(如`VMUL`, `VSQRT`等)。此外,性能分析器可以帮助识别浮点运算的瓶颈,并进一步优化代码。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

De-Chang Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值