yongc语言编写单片机程序,出现了堆栈溢出情况,怎么解决?堆栈指针怎么初始化?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yongc语言编写单片机程序,出现了堆栈溢出情况,怎么解决?堆栈指针怎么初始化?相关的知识,希望对你有一定的参考价值。

参考技术A 可以在连接命令文件中指定堆栈尺寸,并且用特定字符串初始化这些区域,比如初始化成"STACK";然后充分运行程序;用内存观察观察堆栈使用情况(“STACK”被冲掉的部分是使用过的栈区),大致可估算使用堆栈的最坏情况。
根据以上分析,可以设置最佳栈区尺寸,如果栈区使用过大,请优化程序:
-子程序中尽量不要开辟新的大尺寸变量;
-程序调用子程序尽量少使用传入的参数,使用全局变量;
-减少程序中switch语句和循环的嵌套。

使用 gp2c 时堆栈溢出,但在同一程序中直接使用 gp 时不会出现堆栈溢出 (PARI/GP)

【中文标题】使用 gp2c 时堆栈溢出,但在同一程序中直接使用 gp 时不会出现堆栈溢出 (PARI/GP)【英文标题】:Stack Overflow when using gp2c but not when using gp directly with the same program (PARI/GP) 【发布时间】:2021-08-03 23:24:24 【问题描述】:

所以我想使用 gp 计算一个特定投影仪问题的总和。这是不可理解的代码:


n = 10000;
m=100;
sum(k=1,n,eulerphi(k),0.) - (sum(k=1,n,eulerphi(k)*(k * binomial(n-k,m-1) + sum(p = max(m + k - n - 1,1), k-1, (k-p)*binomial(n+p-k-1,m-2),0.)), 0.))/binomial(n,m)

这段代码需要两三分钟才能在我相当普通的机器上输出答案,但它不会超出默认的parisize = 8000000(大约 8 MB 内存)。

现在,我在某处读到 gp2cgp 脚本编译成 c 代码可以提高性能。

所以我刚刚制作了一个program.gp 文件:

calculate() = n = 10000; m=100; sum(k=1,n,eulerphi(k),0.) - (sum(k=1,n,eulerphi(k)*(k * binomial(n-k,m-1) + sum(p = max(m + k - n - 1,1), k-1, (k-p)*binomial(n+p-k-1,m-2),0.)), 0.))/binomial(n,m)

然后使用gp2c-run program.gp 运行它。

在出现的交互式提示中,我刚刚执行了calculate()。然而,令我惊讶的是,即使我将 parisizemax 更改为近 2 GB,我也遇到了堆栈溢出,要求我增加堆栈大小。

? default(parisizemax, 2000000000)
  ***   Warning: new maximum stack size = 2000003072 (1907.352 Mbytes).
? calculate()
  *** calculate: Warning: increasing stack size to 16000000.
  *** calculate: Warning: increasing stack size to 32000000.
  *** calculate: Warning: increasing stack size to 64000000.
  *** calculate: Warning: increasing stack size to 128000000.
  *** calculate: Warning: increasing stack size to 256000000.
  *** calculate: Warning: increasing stack size to 512000000.
  *** calculate: Warning: increasing stack size to 1024000000.
  *** calculate: Warning: increasing stack size to 2000003072.
  ***   at top-level: calculate()
  ***                 ^-----------
  *** calculate: the PARI stack overflows !
  current stack size: 2000003072 (1907.352 Mbytes)
  [hint] you can increase 'parisizemax' using default()

  ***   Break loop: type 'break' to go back to GP prompt

为什么同一个程序在编译到c 时需要这么多额外的内存? 作为参考,n = 1000 而不是 10000 的同一程序仅在将堆栈大小增加到 256000000 (250 MB) 后才显示答案,而仅使用 gp 时只需要默认的 8 MB。有些东西没有加起来。

【问题讨论】:

这确实是一个 [pari] 问题,而不是 [pari-gp]。它看起来像一些内存泄漏问题(因为你只有几个循环)。我建议您浪费时间尝试使用 gp2-c 提高性能。 (没有理由它应该更快)。建议1:去掉0.,用纯整数进行计算。建议 2:内部求和 'sum(p, (k-p)*binomial(n+p-k-1,m-2)' 可能可以在数学上简化以去除总和。 谢谢安德鲁!我会记住你的建议。 【参考方案1】:

默认情况下,gp2cgp2c-run 都不会生成处理 PARI 堆栈的代码,这意味着您将很快得到堆栈溢出。使用gp2c-run -g program.gp-g 标志将导致gp2c 随着计算的进行清理堆栈。 the gp2c tutorial中有这样一个例子。

【讨论】:

是否有充分的理由使用不带 -g 的 gp2c? 三个小问题:没有 GC 语句研究代码核心更简单,您可能希望稍后在(通常很少)真正需要它们的地方手工制作它们,代码可能最终会变成没有 GC 会快一点。但对于快速测试或您不打算查看 C 代码时,-g 应该是您的默认设置。

以上是关于yongc语言编写单片机程序,出现了堆栈溢出情况,怎么解决?堆栈指针怎么初始化?的主要内容,如果未能解决你的问题,请参考以下文章

什么是堆栈溢出?

如果不允许 LP 递归,那么可能会出现堆栈溢出的情况?

(STACK_OVERFLOW)是啥意思?

51单片机死机重启的原因都有哪些?

请问51单片机最大可以运行多大的程序,最好是STC的,C语言

Java堆栈溢出的机制与原理