基于SiFive Freedom-E-SDK的RISC-V向量intrinsics裸机模拟器程序float数组大小≥4096时触发无限循环的原因排查
RISC-V向量Intrinsic裸机程序数组大小≥4096时无限循环问题的排查与解决
我在基于SiFive Freedom-E-SDK构建的RISC-V向量intrinsic函数裸机程序中遇到了一个典型的内存问题,这里分享排查过程和解决方案:
问题现象
当设置float类型数组大小≥4096时,程序会陷入无限循环;但数组大小≤4000时运行完全正常,甚至float16类型数组设为4096也能正常执行。
核心代码
float input[4096]; for (int i=0; i<4096; i++) { input[i] = i; } size_t vl; float* src = input; vfloat32m8_t result; for (int i=4096; i>0; i-=vl) { vl = vsetvl_e32m8(i); vfloat32m8_t operand = vle32_v_f32m8(src, vl); result = vfmul_vv_f32m8(operand, operand, vl); src += vl; }
根本原因分析
这个问题的核心是栈空间不足:
- 你直接在栈上声明了
float input[4096],该数组占用内存为4096 * sizeof(float) = 16384字节(16KB) - Freedom-E-SDK默认的裸机程序栈空间通常刚好小于这个值,当数组大小超过栈的可用容量时,栈溢出会破坏程序的循环控制变量或调用栈结构,最终导致程序进入无限循环
- 而
float16数组4096个元素仅占用8KB内存,float数组4000个元素占用16000字节,均在默认栈空间的临界范围内,因此能正常运行
解决方案
修改Freedom-E-SDK中的链接脚本(通常为.ld后缀文件),增大栈的分配空间:
- 找到链接脚本中定义栈大小的代码,类似:
_stack_size = DEFINED(_stack_size) ? _stack_size : 0x4000; /* 默认16KB */ - 将默认值
0x4000(16KB)调整为更大的数值,比如0x8000(32KB) - 重新编译链接程序后,问题即可解决
内容的提问来源于stack exchange,提问作者Chen CH
相关产品推荐
相关产品推荐

