看看这个问题:Why does a C/C++ compiler need know the size of an array at compile time ?我发现,编译器实现者现在应该有一些时间(现在是10年前的C99标准的一部分)并提供有效的实现。
然而,(从答案中)看起来似乎仍然很昂贵。
这让我感到惊讶。
当然,我理解静态偏移在性能方面比动态偏移要好得多,并且不像一个建议我实际上不会让编译器执行数组的堆分配,因为这可能会花费更多[这还没有测量过;)]
但我仍然对所谓的费用感到惊讶:
当然,问题出现在多个VLA上,我想知道是否有专用的VLA堆栈可行。这意味着VLA将由计数和指针(因此已知大小)表示,并且在辅助堆栈中采用的实际内存仅用于此目的(因此也是堆栈)。
[改写]
如何在gcc / VC ++中实现VLA?
成本真的令人印象深刻吗?
[结束改写]
在我看来,它只能比使用vector
更好,即使是现有的实现,因为你不会产生动态分配的代价(以不可调整大小为代价)。
修改
有部分响应here,但是将VLA与传统阵列进行比较似乎是不公平的。如果我们事先知道尺寸,那么我们就不需要VLA了。在同一个问题中,AndreyT对实现给出了一些指示,但它并不像我想的那样精确。
答案 0 :(得分:4)
如何在gcc / VC ++中实现VLA?
AFAIK VC ++没有实现VLA。它是一个C ++编译器,它只支持C89(没有VLA,没有限制)。我不知道gcc如何实现VLA,但最快的方法是将指针存储到VLA及其大小在堆栈帧的静态部分。通过这种方式,您可以访问其中一个具有常量大小数组的VLA(如果堆栈像x86一样向下扩展,则是最后一个VLA(取消引用[堆栈指针+索引*元素大小+上次临时推送的大小]),和第一个VLA,如果它向上增长(取消引用[stackframe指针+偏离stackframe + index *元素大小]))。所有其他的VLA都需要一个间接来从堆栈的静态部分获取它们的基址。
[编辑:同样在使用VLA时,编译器不能省略堆栈帧基指针,否则这是冗余的,因为堆栈指针的所有偏移都可以在编译期间计算。所以你少了一个免费注册。 - 结束编辑]
成本真的令人印象深刻吗?
不是真的。此外,如果您不使用它,则不需要付费。
[编辑:可能更正确的答案是:与什么相比?与堆分配的向量相比,访问时间将相同,但分配和释放将更快。 - 结束编辑]
答案 1 :(得分:0)
如果要在VC ++中实现,我会假设编译器团队会使用_alloca(size)
的某些变体。我认为成本相当于在堆栈上使用大于8字节对齐的变量(例如__m128
);编译器必须将原始堆栈指针存储在某处,并且对齐堆栈需要额外的寄存器来存储未对齐的堆栈。
因此,开销基本上是一个额外的间接(你必须在某处存储VLA的地址)并且由于在某处存储原始堆栈范围而注册压力。