使用大数组时Rocket Chip仿真失败问题求助
解决Rocket Chip Verilator仿真中大数组导致的运行失败问题
问题根源
你定义的float a[1][3][224][224]数组总大小为:1*3*224*224*4 = 602112字节(约600KB)。RISC-V裸机环境的默认栈空间通常只有几KB到几十KB,这么大的数组直接分配在栈上会触发栈溢出,程序在进入main函数前就因栈空间不足崩溃,因此第一个printf都无法输出。增大L2缓存无效是因为问题根源不在缓存,而是程序启动阶段的栈空间不足。
解决方案
1. 将大数组移到全局/静态区
全局变量和静态变量存储在.data或.bss段,不受栈空间限制,修改方式如下:
// 方式1:定义为静态变量 int main(int argc, char** argv) { printf("CPU+cgra execute Resnet1!\n"); long long unsigned start; long long unsigned end; static float a[1][3][224][224]; // 静态区分配 // 后续代码不变 } // 方式2:定义为全局变量 float a[1][3][224][224]; // 放在main函数外 int main(int argc, char** argv) { printf("CPU+cgra execute Resnet1!\n"); // 后续代码不变 }
2. 使用堆内存动态分配
通过malloc在堆上分配内存,避免栈空间限制,用完后记得释放:
int main(int argc, char** argv) { printf("CPU+cgra execute Resnet1!\n"); long long unsigned start; long long unsigned end; // 计算总元素数并分配堆内存 int total_elements = 1 * 3 * 224 * 224; float* a = (float*)malloc(total_elements * sizeof(float)); if (a == NULL) { printf("Memory allocation failed!\n"); return 1; } int d0 , d1, d2, d3; // 通过索引计算模拟多维数组访问 for(d0 = 0; d0 < 1; d0++){ for(d1 = 0; d1 < 3; d1++){ for(d2 = 0; d2 < 224; d2++){ for(d3 = 0; d3 < 224; d3++){ int idx = d0*3*224*224 + d1*224*224 + d2*224 + d3; a[idx] = d3; } } } } printf("value assign finished!\n"); // 读取数据同理 for(d0 = 0; d0 < 1; d0++ ){ for(d1 = 0; d1 < 3; d1++ ){ for(d2 = 0; d2 < 224; d2++ ){ for(d3 = 0; d3 < 224; d3++ ){ int idx = d0*3*224*224 + d1*224*224 + d2*224 + d3; int I = (int)(a[idx] * 10000); printf("a[%d][%d][%d][%d]:%d\n",d0,d1,d2,d3,I ); } } } } free(a); // 释放堆内存 return 0; }
3. 修改链接脚本增大栈空间
如果坚持要在栈上使用大数组,可以修改项目的链接脚本(通常是.ld文件),增大栈分配:
找到脚本中类似_stack_size = 0x1000;的配置行,将其修改为足够容纳数组的大小,例如:
_stack_size = 0xA0000; // 640KB,大于数组所需的600KB
修改后重新编译链接程序即可。
内容的提问来源于stack exchange,提问作者segmentKOBE
相关产品推荐
相关产品推荐

