Подтвердить что ты не робот

Накладные расходы переменной длины в С++?

Глядя на этот вопрос: Почему компилятору C/С++ нужно знать размер массива во время компиляции?, мне пришло в голову, что разработчики компилятора должны были несколько раз, чтобы получить свои ноги теперь (это часть стандарта C99, что 10 лет назад) и обеспечивают эффективные реализации.

Однако по-прежнему кажется (из ответов) считаться дорогостоящим.

Это меня как-то удивляет.

Конечно, я понимаю, что статическое смещение намного лучше, чем динамическое с точки зрения производительности, и, в отличие от одного предложения, я бы не имел на самом деле компилятор, выполняющий распределение кучи массива, поскольку это, вероятно, стоило бы еще больше [ это не было измерено;)]

Но я все еще удивляюсь предполагаемой стоимости:

  • если в функции нет VLA, тогда не было бы никакой стоимости, насколько я могу видеть.
  • если есть один единственный VLA, тогда можно либо поместить его перед или после всех переменных, и, следовательно, получить статическое смещение для большей части фрейма стека (или, как мне кажется, но я не хорошо разбираюсь в управлении стеком)

Возникает вопрос о нескольких VLA, конечно, и мне было интересно, будет ли работать выделенный VLA-стек. Это означает, что VLA будет отображаться счетчиком и указателем (из известных размеров), а фактическая память, взятая во вторичном стеке, используется только для этой цели (и, следовательно, действительно является стеком).

[перефразировать]

Как VLAs реализованы в gcc/VС++?

Действительно ли это действительно впечатляет?

[end rephrasing]

Мне кажется, что это может быть лучше, чем использование, скажем, vector, даже с существующими реализациями, поскольку вы не несете затраты на динамическое размещение (за счет того, что не изменяете размер).

EDIT:

Существует частичный ответ здесь, однако сравнение VLA с традиционными массивами кажется несправедливым. Если бы мы знали размер заранее, то нам не понадобилось бы VLA. В том же вопросе AndreyT дал некоторые указания относительно реализации, но это не так точно, как хотелось бы.

4b9b3361

Ответ 1

Как VLAs реализованы в gcc/VС++?

AFAIK VС++ не реализует VLA. Это компилятор С++ и поддерживает только C89 (без VLA, без ограничений). Я не знаю, как gcc реализует VLA, но самым быстрым способом является сохранение указателя на VLA и его размер в статической части стекового кадра. Таким образом, вы можете получить доступ к одному из VLA с производительностью массива с постоянным размером (это последний VLA, если стек растет вниз, как в x86 (разыменование [указатель стека + индекс * размер элемента + размер последних временных нажатий]), и первый VLA, если он растет вверх (разыменование [указатель стека/смещение от размера стека/рамки + индекс *))). Все остальные VLA нуждаются в еще одном обращении, чтобы получить свой базовый адрес из статической части стека.

[Редактировать: также при использовании VLA компилятор не может опустить указатель на стек-фрейм, который в противном случае лишний, поскольку все смещения от указателя стека могут быть вычислены во время компиляции. Итак, у вас есть один бесплатный бесплатный реестр. — end edit]

Действительно ли это действительно впечатляет?

Не совсем. Более того, если вы не используете его, вы не платите за него.

[Edit: Возможно, более правильным ответом будет: По сравнению с чем? По сравнению с выделенным кучей вектором время доступа будет таким же, но распределение и освобождение будут быстрее. — end edit]

Ответ 2

Если бы это было реализовано в VС++, я бы предположил, что команда компилятора использует некоторый вариант _alloca(size). И я думаю, что стоимость эквивалентна использованию переменных с более чем 8-байтовым выравниванием в стеке (например, __m128); компилятор должен где-то хранить исходный указатель стека, а для выравнивания стека требуется дополнительный регистр для хранения неуравновешенного стека.

Таким образом, накладные расходы в основном являются дополнительным направлением (вы должны где-то хранить адрес VLA) и регистрировать давление из-за хранения исходного диапазона стека где-то также.