【问题标题】:Timing array static array allocation vs array on stack in C计时数组静态数组分配与C中堆栈上的数组
【发布时间】:2014-11-23 04:39:39
【问题描述】:

我有以下代码,其中包含两个函数,一个分配静态数组,一个分配堆栈上的数组。这些函数运行了很多次并计算了它们的执行时间。堆栈分配始终(略微)比静态分配快。我的印象是,由于静态变量在运行时之前被绑定,因此它的执行速度比分配在堆栈上的数组快

 #include <stdio.h>

#include <stdlib.h>
#include <time.h>
#define MAX_ARRAY 8192 

void statArray()
{
static int statArray[MAX_ARRAY];
}
void stackArray()
{
int stackArray[MAX_ARRAY];
}

int main(int argc, char * argv[]) {
     clock_t start, end;
     double staticTime, stackTime;
     int i;
     int comparisons = 5000000;

     start = clock();
     for (i = 0; i < comparisons; i++) {
          statArray();
     }
     end = clock()-start;
     staticTime = (double)end / CLOCKS_PER_SEC;

     start = clock();
     for (i = 0; i < comparisons; i++) {
          stackArray();
     }
     end = clock() - start;
     stackTime = (double) end / CLOCKS_PER_SEC;

谢谢

反汇编的statArray

 0x0000000000400594 <+0>:   push   %rbp
   0x0000000000400595 <+1>: mov    %rsp,%rbp
   0x0000000000400598 <+4>: leaveq 
   0x0000000000400599 <+5>: retq   

反汇编的stackArray

0x000000000040059a <+0>:    push   %rbp
   0x000000000040059b <+1>: mov    %rsp,%rbp
   0x000000000040059e <+4>: sub    $0x7f88,%rsp
   0x00000000004005a5 <+11>:    leaveq 
   0x00000000004005a6 <+12>:    retq   

【问题讨论】:

  • 为了知道发生了什么,您必须反汇编这两个函数(statArray 和 stackArray)。我的猜测是优化器删除了 stackArray 分配。
  • 编译器可能正在利用指令或缓存,它们允许更快地访问堆栈上的空间而不是内存中的其他空间。预先计算的地址理论上更快,当然,但这可能是用数组的基地址加载寄存器的一次性差异。正如@Steen 所说,如果您想确切地知道发生了什么,请查看生成的代码。 (一个很好的例子,说明为什么在你知道什么是重要的之前你不应该担心微优化代码。专注于算法,而不是诡计,直到你有踪迹并知道什么诡计值得付出努力。)
  • @keshlam 这是 Sebesta 的编程语言概念的练习,它不是为了任何类型的微优化,而是为了理解堆栈、堆和静态分配之间的概念。我的结果与我的预期不同,所以我想知道结果是错误的还是我的预期。也就是说,我已将反汇编函数添加到问题中
  • 大声笑,尝试关闭所有优化并重试。即使这样,您也可能必须实际触摸元素以确保数组实际被分配。
  • 当我用我的编译器为你的函数打开优化时,两者完全一样,它们什么都不做,函数的唯一汇编语句是retq

标签: c arrays static stack


【解决方案1】:

正如你在汇编列表中看到的,statArray 是一个空函数,stackArray 包含单个分配指令(sub rbp, imm)。该指令的时间效应可能被序言/尾声指令的延迟所隐藏,并且只能使用 cpu 温度计来测量差异。您遇到的实际差异是由于轻微的时间测量错误,如果您交换代码块的顺序,可能会发生变化。

编辑:值得注意的是,堆栈分配只不过是通过从堆栈指针寄存器中减去来修复堆栈顶部,而不涉及任何复杂的逻辑(与 malloc 相对),并且静态与堆栈“速度”似乎是一个常见的误解。

【讨论】:

    猜你喜欢
    • 2014-12-14
    • 2021-05-20
    • 1970-01-01
    • 2014-01-31
    • 2013-12-21
    • 2019-07-24
    • 2018-09-17
    • 2018-06-06
    • 2010-11-27
    相关资源
    最近更新 更多