当我将我的可执行文件链接到我自己用Crosstool-NG构建的libc时,我的程序的执行速度要比将我的可执行文件链接到由Nucleisys公司构建并由Platformio项目提供的libc慢得多。在视觉上,它不会欺骗。大约2米30对10米以上与我的。(解决/稳定康威生命博弈)
实际上,当我这样做时:
mv ~/x-tools/riscv32-unknown-elf/riscv32-unknown-elf/lib/rv32imac/ ~/x-tools/riscv32-unknown-elf/riscv32-unknown-elf/lib/original_rv32imac
如果我重新编译,显然编译失败了:
error : /home/th/x-tools/riscv32-unknown-elf/lib/gcc/riscv32-unknown-elf/9.4.0/../../../../riscv32-unknown-elf/lib/libc.a(lib_a-atexit.o): can't link double-float modules with soft-float modules
...
然后部署Nuclei库:
cp -a ~/.platformio/packages/toolchain-gd32v/riscv-nuclei-elf/lib/rv32imac ~/x-tools/riscv32-unknown-elf/riscv32-unknown-elf/lib/
我不做其他的事。我不动我的makefile。然后,我重新编译,只看到执行速度。我错过了什么?
两个libc似乎是相同的,它们都是soft-float ABI。
PS:我在裸机环境中,我用-march= rv 32 imac-mabi= ilp 32编译
编辑1:下面,crosstool-NG设置的主开关编译我的libc(newlib):
'--disable-newlib-io-float'
'--disable-newlib-io-long-double'
'--enable-newlib-supplied-syscalls'
'--disable-newlib-io-pos-args'
'--disable-newlib-io-c99-formats'
'--disable-newlib-io-long-long'
'--disable-newlib-register-fini'
'--enable-newlib-nano-malloc'
'--enable-newlib-nano-formatted-io'
'--enable-newlib-atexit-dynamic-alloc'
'--disable-newlib-global-atexit'
'--disable-lite-exit'
'--disable-newlib-reent-small'
'--enable-newlib-multithread'
'--disable-newlib-retargetable-locking'
'--enable-newlib-wide-orient'
'--enable-newlib-fseek-optimization'
'--enable-newlib-fvwrite-in-streamio'
'--enable-newlib-unbuf-stream-opt'
'--enable-target-optspace'
编辑2:A link to the two version of ELF files. The fast and the slow
编辑3:两个版本的可执行文件的readelf输出之间的比较。我们可以看到在快速版本,一个头,我没有在缓慢:init_array.也许是线索。。
编辑4:
如果我没有弄错的话,SP寄存器在_start函数中初始化:
la sp, _sp
_sp在链接器中定义。脚本:
ram (wxa!ri) : ORIGIN = 0x20000000, LENGTH = 32K
__stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
[....]
. = ALIGN(8); PROVIDE( _end = . ); /*0X2000,0340*/
PROVIDE( end = . );
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size : {
PROVIDE( _heap_end = . ); . = __stack_size;
PROVIDE( _sp = . );
} >ram AT>ram
在这两种情况下,GDB(信息寄存器)告诉我:(sp)0x20008000。我再查一遍
编辑5:只要重做链接+objcopy就足以看出问题所在。(或者反过来,问题的正确解决)。不需要重新编译。
第6章:一个很严重的问题:两个libc版本之间的memcpy实现有很大的不同:(
编辑7:没有关于编辑6的运气。用本地实现替换主循环中的memcpy并不能解决任何问题。我的libc还是慢,另一个快。这让我抓狂:(
1条答案
按热度按时间5us2dqdw1#
我的libc(newlib)没有使用
_HAVE_INIT_FINI
选项编译:_init()
是libc的外部函数,必须在其项目中定义。在我的项目_init()
中,如果调用,设置mcu的频率。在我的情况下,它没有被称为。