Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的RAM优化:堆栈还是全局变量?_C_Memory_Stack_Global Variables - Fatal编程技术网

C语言中的RAM优化:堆栈还是全局变量?

C语言中的RAM优化:堆栈还是全局变量?,c,memory,stack,global-variables,C,Memory,Stack,Global Variables,我正在给我用C编写的相当大的项目添加(还有)另一个子模块,我想在我的小处理器上运行。现在我想知道:我的新模块可能很小,但它需要在每个周期积累相当多的中间信息,以便计算其内容。我创建了一个数据结构来保存所有这些中间数据,这就是我想知道的: 我可以简单地在模块源文件中创建此数据结构的全局实例,在模块中的任何地方都可以随时使用。但这意味着,即使在其他模块运行时,该中间数据的大小也会被恒定的RAM占用。这就是我最初拥有的,这在任何方面都不是最优的 我可以在更新周期开始时创建此数据结构的本地实例,并始终

我正在给我用C编写的相当大的项目添加(还有)另一个子模块,我想在我的小处理器上运行。现在我想知道:我的新模块可能很小,但它需要在每个周期积累相当多的中间信息,以便计算其内容。我创建了一个数据结构来保存所有这些中间数据,这就是我想知道的:

  • 我可以简单地在模块源文件中创建此数据结构的全局实例,在模块中的任何地方都可以随时使用。但这意味着,即使在其他模块运行时,该中间数据的大小也会被恒定的RAM占用。这就是我最初拥有的,这在任何方面都不是最优的
  • 我可以在更新周期开始时创建此数据结构的本地实例,并始终向每个函数传递指向它的指针。但从编码的角度来看(长函数原型)这很可怕,这意味着每次调用另一个函数时,我都必须在堆栈顶部添加该指针的另一个副本(对吗?)
  • 我还可以创建一个全局变量(作用域为我的模块),它只是指向中间数据的指针。这意味着一个8位整数会一直存在(即使所有模块都在运行),但不会更多。然后,可以从模块中的任何地方访问数据,而无需堆栈开销和长函数原型
关于我的系统的一些信息:模块一个接一个地运行,重新进入只是为了得到结果,而不是执行进一步的计算。中间数据实际上只在每个模块的更新调用期间需要,并且它们总是以相同的顺序出现

哪种解决方案最好?在哪种情况下?编译器在哪里发挥作用?这里有我不知道的一般记忆机制吗


提前感谢您的澄清

这在很大程度上取决于您使用的系统类型,以及最重要的是执行速度或内存消耗。我认为“小处理器”是指微控制器。你没有提到再进入,所以我认为这不是一个问题

在这种情况下,如果您认为拥有一个文件范围结构会浪费内存,那么您只是在愚弄自己。因为你总是要为最坏的情况而设计,这里最坏的情况是调用一个需要使用结构的函数。此时,最坏情况下的内存消耗总量将涉及到该结构,并且无论该结构是在文件范围还是在堆栈上分配,它都将始终是相同的

如果你没有足够的内存来处理最坏的情况,那么世界上没有任何分配方法可以拯救你。“暂时保存一些内存”没有任何意义。在不运行最坏情况时保存一些内存是无关紧要的。在最坏的情况下,你仍然需要有足够的内存——要么有,要么没有

因此,最好的选择是将结构保留在文件范围内,因为这不会影响内存消耗,但可以节省执行时间


如果您的模块需要线程安全或允许多个实例,那完全是另一回事。

这在很大程度上取决于您使用的系统类型,以及最重要的是执行速度或内存消耗。我认为“小处理器”是指微控制器。你没有提到再进入,所以我认为这不是一个问题

在这种情况下,如果您认为拥有一个文件范围结构会浪费内存,那么您只是在愚弄自己。因为你总是要为最坏的情况而设计,这里最坏的情况是调用一个需要使用结构的函数。此时,最坏情况下的内存消耗总量将涉及到该结构,并且无论该结构是在文件范围还是在堆栈上分配,它都将始终是相同的

如果你没有足够的内存来处理最坏的情况,那么世界上没有任何分配方法可以拯救你。“暂时保存一些内存”没有任何意义。在不运行最坏情况时保存一些内存是无关紧要的。在最坏的情况下,你仍然需要有足够的内存——要么有,要么没有

因此,最好的选择是将结构保留在文件范围内,因为这不会影响内存消耗,但可以节省执行时间


如果您的模块需要线程安全或允许多个实例,那完全是另一回事。

听起来您也认为第三种解决方案是最好的。是的。我想确定,这样我就可以公正、完整地提出问题。我还想知道长函数原型和在所有函数调用中堆积同一个指针是否是真正的问题。第一和第三都有重新进入的问题。根据我的经验,创建基于global的模块在任何时候都会有一些问题,特别是如果您使用嵌入式RTOS。而传递指针对堆栈的影响并不是很重要(通常是cas)。对我来说,第一个和第三个解决方案之间的差异非常小(只有ram占用),您有所有的不便之处。(我所说的只是一般情况,对于具体情况,当然,我的论点不成立)您在另一条评论中提到,您的模块一个接一个地运行。如果全局数据只在一个模块的生命周期内需要,并且如果其他模块具有类似的全局数据需求,那么您可以查看类似链接器覆盖的内容。例如GNU链接器(),但是您正在使用的任何链接器都可能有类似的功能。这会给你一个类似于列表中的#1的方法,但没有你的终身担忧。听起来你也认为你的第三个解决方案是最好的。是的。我想确定,这样我就可以公正、完整地提出问题。另外,我想知道长功能原型和堆叠