我的代码会调用嵌入式系统的FPU吗?定点实现泰勒展开疑问
问题:判断定点运算中乘法是否调用FPU
我手上有一款搭载FPU的嵌入式处理器,现在想完全用整数和定点运算实现e^x的泰勒级数求值(不调用FPU)。在实现Horner法则时,关键语句是res += x*int_polynomial[i];——其中x是float类型,res、int_polynomial是整数类型。目前求值结果是对的,但不确定这个乘法操作会不会偷偷调用FPU,想知道怎么判断。
完整代码如下:
#include <stdio.h> #include <math.h> #define N 7 // 6阶多项式 #define Q 15 #define E_CONST 2.718281828459045 int factor_ = 1<<Q; float taylor_coeffs[] = {1.000000,1.000000, 0.500000, 0.166667,0.041667, 0.008333, 0.001389}; int int_polynomial[N] = {0}; void get_int_coeffs() { int i; for(i = 0; i<N; i++) { int_polynomial[i] = taylor_coeffs[i]*factor_; } } double horners_rule(float x) { long long res; double res_; int i; for(i=0,res=0; i<N; i++) { res += x*int_polynomial[i]; } return res_ = (float)res/factor_; // 另一种写法: // res_ = res; // 将res的值存入double类型变量 // return res_ /= factor_; // 除法后返回 } float error_(double y, double y_hat) { return sqrt(pow(y-y_hat,2)); } int main() { double y_hat; float eval_error; get_int_coeffs(); y_hat = horners_rule(1); eval_error = error_(E_CONST,y_hat); printf("多项式求值结果 y_hat = %lf\n",y_hat); printf("误差 = %f\n",eval_error); }
判断方法
1. 查看编译后的汇编代码
这是最直接准确的方式:
- 使用你的嵌入式编译器(如ARM GCC)编译代码时,添加生成汇编的参数(ARM GCC用
-S),输出对应的汇编文件; - 定位到
horners_rule函数中对应x*int_polynomial[i]的汇编指令:- 如果出现FPU相关指令(比如ARM架构的
VMUL.F32、VADD.F32这类VFP指令),说明该乘法调用了FPU; - 如果是整数乘法指令(如ARM的
MUL、MLA),配合定点数的移位或调整操作,说明是纯整数运算,未调用FPU。
- 如果出现FPU相关指令(比如ARM架构的
2. 通过编译器选项控制与验证
- 检查当前编译是否启用了FPU优化:比如ARM GCC的
-mfpu=系列参数(如-mfpu=vfpv3),若开启该类参数,编译器可能会将float参与的运算转换为FPU指令; - 强制禁用FPU:尝试添加编译选项(如ARM架构的
-msoft-float),强制编译器用软件模拟浮点运算。如果编译后代码能正常运行且结果正确,说明原乘法操作未依赖FPU;若编译报错或运行异常,说明之前的操作确实调用了FPU。
3. 调试时观察FPU寄存器状态
- 使用嵌入式调试工具(如J-Link配合GDB)连接处理器,在
horners_rule的乘法语句处设置断点; - 执行到断点后,查看FPU寄存器(如ARM架构的S0-S31浮点寄存器):
- 若这些寄存器的值在乘法操作前后发生变化,说明FPU被调用;
- 若无变化,说明是纯整数运算,未使用FPU。
内容的提问来源于stack exchange,提问作者Rotem Calisir
相关产品推荐
相关产品推荐

