c - 在 elf-gcc 中,exp() 只在第一次调用时正常工作,之后就不行了

标签 c gcc linker floating-point sparc

我正在使用我们团队开发的处理器(sparc 架构)和 gcc elf 工具链在我们的电路板上使用裸机程序(无操作系统)运行耗时的算法。使用soft-float,效果很好,一个多小时后得到了想要的结果(纯软件运行,后期用特殊硬件会大大缩短)。但是使用 hard-float,我可以在 15 分钟内完成,效果不错。好的,但在某些硬浮点配置中,我发现 exp() 函数无法正常工作。这种情况是我想正确打印 float 的地方。

我写了一个测试代码来测试exp()函数,

ab_printf("------- exp test--------\n");
float a[5] = {-0.438984, -0.357934, 0.174203, 0.280720, 0.372380};
for(i=0;i<5;i++){
ab_printf("x = %f, y = %f\n", a[i], 1./(1.+exp(-1.*a[i])));
}
ab_printf("------- end of exp test--------\n");

当我使用软 float (在 Makefile 中使用 -msoft-float)时,我得到了正确的结果。

------- exp test--------
x = -0.438984, y = 0.391983
x = -0.357934, y = 0.411460
x = 0.174203, y = 0.543441
x = 0.280720, y = 0.569723
x = 0.372380, y = 0.592034
------- end of exp test--------

然后,我切换到硬浮点(使用硬件 FPU,= 删除 -msoft-float 以生成硬件浮点指令),但我知道 exp() 函数是由工具集使用软件实现的。 (CPU中没有exp指令。所以工具链库会用Taylor展开什么的。。)。使用 hard-float 时,我使用如下两个库作为链接器。

LIBS        +=  -L/opt/abde/lib/gcc/sparc-ab-elf/4.6.2/soft/v8   # line 1
LIBS        +=  -L/opt/abde/sparc-ab-elf/lib/soft/v8    # line 2

如果我在第 1 行中使用 v8 而不是 soft/v8,程序会在打印 float 时停止,所以这不是一个选项。我怀疑我的工具集没有正确构建,但我现在无法在我的系统中构建它。

如果我在第 2 行中使用 v8 而不是 soft/v8,我会看到 float 的乱码数据。但是我知道我可以在此设置中获得良好的检测结果,尽管我看到随着处理的进行会出现一些小的浮点错误,而且我知道在此设置中 exp() 函数无论如何也可以工作(因此 15 分钟后的最终正确结果) .

在硬 float 模式下,当我从 i = 0 开始运行时,它给了我这个结果(只有第一个工作正确):

------- exp test--------
x = -0.438984, y = 0.391983
x = -0.357934, y = 1.000000
x = 0.174203, y = 1.000000
x = 0.280720, y = 1.000000
x = 0.372380, y = 1.000000
------- end of exp test--------

当我从 I = 1 运行它时,它给了我(而且,只有第一个正确)

------- exp test--------
x = -0.357934, y = 0.411460
x = 0.174203, y = 1.000000
x = 0.280720, y = 1.000000
x = 0.372380, y = 1.000000
------- end of exp test--------

这会是什么情况?问题是我现在无法在我的系统上构建工具链。

最佳答案

让程序使用 float 而不是 double 值。如果你使用像 1.0 这样的文字,它是双倍的。请改用 1.0f。 exp 采用 double 参数并返回 double 。

1.+exp(-1.*a[i]) 会将 a[i] 转换为 double,然后执行 double 运算,然后再次转换为 single float。它对精度有相当重要的影响。我不知道您的 FPU 使用什么数字(32 位或 64 位)。使它们都与 FPU 相同。

请注意,根据浮点类型(expf、exp、expl),您有不同的 exp 函数

关于c - 在 elf-gcc 中,exp() 只在第一次调用时正常工作,之后就不行了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45030232/

相关文章:

c++ - 单独文件中命名空间中的函数模板可以正常编译,但链接器找不到它

c++ - 如何填写全局偏移表?

c++ - malloc 分配的内存可以使用多少时间?

c++ - 为什么参数不是常量表达式?

c++ - 在这种情况下,我们可以使用 "signed"到 "unsigned"的技巧来保存一次比较吗?

c - gcc 自动更正 printf 中的格式

c++ - Friend 模板函数类内定义

c++ - OpenCV 安装,未解析的外部符号

c - 这种散列任何通用对象的方法是否正确?

c - 这里的算法发生了什么,代码与 C 中的递归问题有关?