保留在堆栈上的数组大小是否会影响内存使用以外的任何其他资源?

Does the size of an array, reserved on the stack, influence any other resource than memory usage?

这只是出于兴趣,我个人使用 C++Builder 2009

假设我分配:wchar_t Buffer[32] 或者我分配 wchar_t Buffer[512]

第二次调用分配了更多内存,因此您可能会争辩说第二次调用在内存使用方面更昂贵。

但是,以这种方式分配更多内存是否还会影响其他任何事情?是否涉及更多说明?更多 CPU 用法?

只是想知道?

我认为如果你在相同的范围内调用第一个,意味着相同数量的比特,那么最好使用 wchar_t Buffer[512] 只是因为它会花费更长的时间,而且我相信,使用更多资源来启动呼叫退出,然后启动另一个呼叫,并继续进行。但是对于第二个,你有一个开始,然后它与那个任务相关联,只要你暂时不想做任何其他事情就可以了。希望对您有所帮助。

通过分配更多大小,指令不会有任何差异。 此外,堆栈内存在编译时是已知的,编译器会生成所需的指令。

例如::

int main()
{
    char Buffer[1024] ;
    char Buffer2[ 512] ;
 return 0 ;
}

00981530  push        ebp  
00981531  mov         ebp,esp  
00981533  sub         esp,6DCh   //6dch = 1756  just the esp is adjusted to allocate more memory
00981539  push        ebx  

int main()
{
    char Buffer[32] ;
    char Buffer2[ 512] ;
  return 0 ;
}

00D51530  push        ebp  
00D51531  mov         ebp,esp  
00D51533  sub         esp,2FCh  //2fch = 764 now the esp is adjusted to 764 without any instruction change.
00D51539  push        ebx  

是否涉及更多指令? 没有,你可以看看上面的例子:)

更多 CPU 用法? 不,因为执行了相同数量的指令

更多内存使用? 是的,因为分配了更多的堆栈内存。

这是“'allocating'”堆栈内存。所有这一切都需要调整堆栈指针。如果你写一个像这样的函数:

void foo()
{
    char c[32];
    ...
}

生成的程序集看起来像(在 64 位机器上):

.cfi_startproc
pushq   %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16 
movq    %rsp, %rbp
.cfi_def_cfa_register 6
subq    , %rsp        // This is the actual "allocation" on the stack

如果将其更改为 char c[512],唯一改变的是:

subq    8, %rsp // Allocation of 512 bytes on stack

CPU 指令或所需时间没有区别。唯一的区别是第二个使用了更多有限的堆栈内存。

However, is anything else also possibly affected by allocating more memory this way ?

可能会产生一个相关的副作用:当您为缓冲区分配更多内存时,程序需要访问的堆栈页面被拆分到更多缓存行的可能性就会增加,这最终可能意味着 CPU 必须等待否则不会发生的缓存未命中。请注意,这里没有特别的理由认为您正在使用更多缓冲区:"problem" 可能会要求 CPU 在缓冲区之前和之后获取数据,以及所有可能会被分割成更多的缓存行。缓冲区周围的这些堆栈页面可能会被频繁访问以将它们保留在缓存中,但这样做可能会弹出一些暂时未使用的缓存内容,并且 if 稍后需要,然后你有缓存未命中。缓存行的粒度(每个 "page" 有多少字节)也会影响结果。

这通常是完全无关紧要的,但你问了...;-)。

Are there more instructions involved ?

不涉及更多指令。

More CPU usage ?

等待缓存的时间是 "usage"。

在操作系统中,称为动态加载 的内存管理实现仅在调用时加载例程,而不是将程序中的所有例程加载到主内存中。加载例程时,必须将其所有元素的地址加载到页面 table 以进行地址转换。对应于特定地址的内容被加载到名为 page.

的单元中

页面大小通常为 2kb 或 4kb 的较小数量级。如果内容超过页面大小,则会拆分并占用多个页面。当 page fault occurs a new content is loaded overwriting the older content based on page replacement policies 到一个交换 space。当再次需要替换的内容时,MMU 将再次从 swap space 加载内容到页面。这个

让我们想想如果加载和交换涉及更大的内容会发生什么,这是一个性能问题并且涉及一些 cpu 周期。

根据您的问题,这对大小为 32 或 512 的 wchar_t 数组没有影响。但是大小以兆字节为单位的不同数据结构和这种结构的数组以数千为单位会产生一些影响关于内存和 CPU。我建议你看看here.