gcc 为什么执行速度取决于使用的libc?

1sbrub3j  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(239)

当我将我的可执行文件链接到我自己用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还是慢,另一个快。这让我抓狂:(

5us2dqdw

5us2dqdw1#

我的libc(newlib)没有使用_HAVE_INIT_FINI选项编译:

void __libc_init_array (void) {
// ...
#ifdef _HAVE_INIT_FINI
  _init ();
#endif

_init()是libc的外部函数,必须在其项目中定义。在我的项目_init()中,如果调用,设置mcu的频率。在我的情况下,它没有被称为。

相关问题