看这个问题: 为什么C/C ++编译器需要在编译时知道数组的大小? 在我看来,编译器实施者现在应该有一段时间才能弄湿他们的脚(这是10年前C99标准的一部分)并提供有效的实施。

但是,似乎仍然(从答案)被认为是昂贵的。

这让我感到惊讶。

当然,我知道在性能方面,静态偏移量比动态偏移量要好得多,而且与一个建议不同,我实际上不会让编译器执行阵列的堆分配,因为这可能会花费更多的成本[这还没有[这还没有被测量;)

但是我仍然对那个想象的 成本:

  • 如果函数中没有VLA,那么我可以看到的不费用。
  • 如果有一个vla,那么可以将其放在所有变量之前或之后,因此在大多数堆栈框架中都会获得静态偏移(在我看来,但我并没有很好地参与堆栈管理)

当然,有多个VLA的问题出现了,我想知道拥有专用的VLA堆栈是否会起作用。这意味着比VLA以计数和指针(因此已知的大小)表示,并且仅用于此目的的次要堆栈中获得的实际记忆(因此也确实是一个堆栈)。

rephrasing

GCC / VC ++中如何实现VLA?

成本真的如此令人印象深刻吗?

结束改头

在我看来,它只能比使用 vector, ,即使有目前的实施,由于您不会产生动态分配的成本(以无法解析的成本)。

编辑:

有部分回应 这里, 但是,将VLA与传统阵列进行比较似乎不公平。如果我们事先知道大小,那么我们将不需要VLA。在同一个问题中,安德烈特(Andreyt)就实施做出了一些指控,但这并不像我想要的那样精确。

有帮助吗?

解决方案

GCC / VC ++中如何实现VLA?

AFAIK VC ++不实现VLA。它是C ++编译器,仅支持C89(无VLA,无限制)。我不知道GCC如何实现VLA,但最快的方法是将指针存储到VLA及其大小中的指针中,并将其大小存储在堆栈框架的静态部分中。这样,您可以使用恒定数组的性能访问其中一个VLA(如果堆栈像x86中的堆栈向下生长,这是最后一个vla(derference [stack pointer + index*元素大小)第一个VLA如果它向上生长(deReference [stackframe pointer +从stackframe + index*元素大小))))。所有其他VLA都需要再间接地从堆栈的静态部分获取基地地址。

[ 编辑: 同样,当使用VLA时,编译器无法省略堆栈框架指针,否则是冗余的,因为可以在编译时间内计算堆栈指针的所有偏移。因此,您的免费注册较少。 - 结束编辑 ]

成本真的如此令人印象深刻吗?

并不真地。此外,如果您不使用它,则不为此付费。

[ 编辑: 可能是一个更正确的答案:与什么相比?与分配的矢量相比,访问时间将相同,但分配和交易速度将更快。 - 结束编辑 ]

其他提示

如果要在VC ++中实施,我认为编译器团队将使用某种变体 _alloca(size). 。而且我认为成本等同于在堆栈上使用超过8字节对齐的变量(例如 __m128);编译器必须将原始的堆栈指针存储在某个地方,并且对齐堆栈需要额外的寄存器来存储未对齐的堆栈。

因此,开销基本上是一个额外的间接区域(您必须存储VLA的地址),并且由于将原始堆栈范围存储在某个地方而导致的压力。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top