Re[2]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 16:57
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>За все компляторы и платформы, конечно, не скажу, ограничусь x86. Но, думаю, в других системах то же.


PD>Когда все массивы статические, суммарный объем данных , размещаемых на стеке, при входе в функцию известен до ее выполнения. Поэтому компилятор просто строит код, изменяющий значение регистра стека на суммарный объем. Кстати, по крайней мере VC++ делает это именно при входе в функцию, а не при входе в блок, как вроде бы требовалось. Поэтому в пределах функции значение регистра стека не меняется (конечно, оно изменится, если внутри этой функции войти в другую, но тогда в другой будет то же самое, а выйдем — вернемся в исходное состояние вызываюшей функции). Поэтому адреса всех стековых переменных (и массивов, и скаляров) можно определить в момент входа в функцию и они в ней меняться не будут. В x86 для этого используется базирование по регистру EBP.

Именно! Именно ebp!

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.

Указатель на текущий фрейм стека сохраняется в ebp. Но выделение массива на стеке его не затрагивает, это выделение делается изменением регистра esp. Ну то есть адресация всех локальных переменных внутри функции никак не изменяется, она не зависит от esp, так как базой служит ebp, а на этот регистр стековые массивы никак не влияют. Никаких там падений скорости нет, код доступа к локальным переменным даже не меняется.
Re[2]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 17:00
Оценка:
Здравствуйте, x-code, Вы писали:

XC>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.

А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.
Re[4]: Динамический массив на стэке
От: Sni4ok  
Дата: 07.09.11 17:00
Оценка: :)
Здравствуйте, dilmah, Вы писали:


S>>например затем, что выделение на стеке элементарная мгновенная операция


D>с чего это. Там каждой страницы нужно касаться


ну мне казалось там просто изменение регистра- но не суть, всё равно по сравнению с malloc'ом это как стринги по сравнению с понталонами.
Re[3]: Динамический массив на стэке
От: dilmah США  
Дата: 07.09.11 17:25
Оценка:
XC>>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.
WM>А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.

тем не менее в Си неполноценная поддержака этого.
Скажем, ты не можешь вызвать функцию с переменным и *динамически* определяемым кол-вом аргументов
Re: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:31
Оценка:
Здравствуйте, Muxa, Вы писали:
M>Почему нельзя сделать вот так?

Как выше уже отметили, в C99 можно. Почему же нельзя в C++ — тому две причины.

1. Для int, вроде, никаких проблем, как и для других POD, а вот насчёт классов с деструктором не уверен. Особенно учитывая исключения.
2. Если в функции есть массив переменного размера, то будет, как заметил Pavel Dvorkin, небольшой оверхед (даже если его не использовать).

В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:33
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.

А всё это лишние команды, лишние такты.
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 17:35
Оценка:
Здравствуйте, watch-maker, Вы писали:
WM>Указатель на текущий фрейм стека сохраняется в ebp.

А ведь можно было бы и не сохранять. Вот на этом и оверхед.
Re[4]: Динамический массив на стэке
От: watch-maker  
Дата: 07.09.11 17:45
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, watch-maker, Вы писали:

WM>>Указатель на текущий фрейм стека сохраняется в ebp.

MOP>А ведь можно было бы и не сохранять. Вот на этом и оверхед.

Ну детский сад прямо. Этот оверхед — две инструкции. И во-первых, фреймы стека и так много где используются, независимо от поддержки VLA. Во вторых, компилятору ничего не мешает не включать фреймы, если в конкретной функции нет VLA. В-третьих, это всё равно в тысячи раз быстрее, чем выделение массива в куче.
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 18:01
Оценка:
Здравствуйте, watch-maker, Вы писали:
WM>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, watch-maker, Вы писали:
WM>>>Указатель на текущий фрейм стека сохраняется в ebp.
MOP>>А ведь можно было бы и не сохранять. Вот на этом и оверхед.
WM>Ну детский сад прямо. Этот оверхед — две инструкции. И во-первых, фреймы стека и так много где используются, независимо от поддержки VLA. Во вторых, компилятору ничего не мешает не включать фреймы, если в конкретной функции нет VLA. В-третьих, это всё равно в тысячи раз быстрее, чем выделение массива в куче.

Не в тысячи, а всего лишь в 2-3 раза (или около того), если использовать специальный аллокатор. Притом в момент запроса (всё равно инициализация массива съест больше), а не при входе в функцию (даже если массив не понадобился).

И если практически того же самого легко добиться самому, то зачем менять язык? Он и так сложный.
Re[4]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 18:31
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Здравствуйте, Pzz, Вы писали:

Pzz>>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.

MOP>А всё это лишние команды, лишние такты.


Указатель на стек на входе все равно удобно иметь под рукой, чтобы добираться до параметров. Большинство компиляторов все равно генерируют enter/leave (или эквиавалент), независимо от наличия alloca() или массивов переменной длинны
Re[5]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 18:46
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Здравствуйте, Pzz, Вы писали:
Pzz>>>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности (напомню, стек на x86 растет вниз). На выходе восстанавливаем указатель стека из регистра. Команды enter/leave делают это автоматически.
MOP>>А всё это лишние команды, лишние такты.
Pzz>Указатель на стек на входе все равно удобно иметь под рукой, чтобы добираться до параметров. Большинство компиляторов все равно генерируют enter/leave (или эквиавалент), независимо от наличия alloca() или массивов переменной длинны

Указатель на стек всё равно есть в подавляющем большинстве современных платформ (у которых вообще есть стек). Обращаться по константному смещению от вершины стека одинаково удобно, независимо от количества локальных переменных. От дорогих enter/leave компиляторы избавляются при включенной оптимизации (особенно от конкретно enter/leave).
Re[2]: Динамический массив на стэке
От: Ops Россия  
Дата: 07.09.11 18:59
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>В то же время, потребности полностью удовлетворяются vector и scoped_array (возможно, с пользовательским аллокатором). Не менее (если не более) эффективно. Зачем вводить в язык синтаксическую конструкцию, если задачу можно решить существующими средствами?


Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Динамический массив на стэке
От: gegMOPO4  
Дата: 07.09.11 19:14
Оценка:
Здравствуйте, Ops, Вы писали:
Ops>Зачем вообще высокоуровневые языки, когда абсолютно все, что они могут, можно реализовать на асме?

Т.е. вы не понимаете, почему vector, string и iostream реализованы на C++, а не являются примитивами языка?
Re[2]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 07.09.11 19:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>В x86 для этого используется базирование по регистру EBP.


Может использоваться базирование по EBP, для отладки; а так: omit frame pointer и вперед.

PD>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.


Никто не требует размещать переменные в стеке в порядке их объявления и никто не запрещает размещать динамические массивы в стеке после всех остальных переменных.
Re[3]: Динамический массив на стэке
От: x-code  
Дата: 07.09.11 19:51
Оценка:
Здравствуйте, watch-maker, Вы писали:

XC>>А почему нельзя как-то вынести на уровень языка динамическое добавление и извлечение объектов из системного стека? Многие алгоритмы таковы, что нужно насоздавать какое-то заранее неизвестное количество объектов из входных данных, и затем их обработать.

WM>А по-твоему как функция printf работает? Поддержка переменного числа аргументов в функциях так и реализована в языке с самого начала.

Я говорю о прямом ручном размещении объкетов в стеке, через push, и извлечении через pop. Да, это небезопасно, можно случайно повредить стековые переменные или адрес возврата, но ведь на то он и Си чтобы быть небезопасным, да и чтобы повредить переменные есть гораздо более простые способы
Re[6]: Динамический массив на стэке
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.09.11 22:46
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Указатель на стек всё равно есть в подавляющем большинстве современных платформ (у которых вообще есть стек). Обращаться по константному смещению от вершины стека одинаково удобно, независимо от количества локальных переменных. От дорогих enter/leave компиляторы избавляются при включенной оптимизации (особенно от конкретно enter/leave).


У большинства, кстати, указателя стека именно что нету. В качестве такового используется регистр общего назначения.

Компилятор избавляется от возни со стеком, если функция достаточно "простая" для этого. Наличие или отсутствие alloca или эквиавалента — лишь еще один критерий простоты.
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:44
Оценка:
Здравствуйте, MescalitoPeyot, Вы писали:

MP>Никто не требует размещать переменные в стеке в порядке их объявления


Я об этом и не говорил.

>и никто не запрещает размещать динамические массивы в стеке после всех остальных переменных.


После — это как ?


{
  int x;
  int y[n];
  {
    int z;
    int t[m];


Кто тут после кого ?
With best regards
Pavel Dvorkin
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:52
Оценка:
Здравствуйте, watch-maker, Вы писали:

PD>>Если допустить, что память может внутри функции выделяться на переменный размер, то от этой простой схемы ничего не останется. Придется существенно усложнять код выделения, а значит, упадет скорость. Выгода не перекрывает проблем.

WM>Указатель на текущий фрейм стека сохраняется в ebp. Но выделение массива на стеке его не затрагивает, это выделение делается изменением регистра esp. Ну то есть адресация всех локальных переменных внутри функции никак не изменяется, она не зависит от esp, так как базой служит ebp, а на этот регистр стековые массивы никак не влияют.

Отлично. Раскажи, как ты будешь получать доступ к локальным переменым через EBP, если при входе в функцию размещается два динамических массива. Они же тоже локальные переменные, к ним тоже надо добраться
With best regards
Pavel Dvorkin
Re[3]: Динамический массив на стэке
От: Pavel Dvorkin Россия  
Дата: 08.09.11 00:54
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ой, да ладно. На входе сохраняем указатель стека в другом регистре и декрементируем его по мере надобности


Чуть подробнее, пожалуйста. На входе куда : в функцию ? в блок ?
With best regards
Pavel Dvorkin
Re[4]: Динамический массив на стэке
От: MescalitoPeyot Украина  
Дата: 08.09.11 01:34
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>
PD>{
PD>  int x;
PD>  int y[n];
PD>  {
PD>    int z;
PD>    int t[m];
PD>


PD>Кто тут после кого ?


push    ebp  
mov     ebp,esp
sub     esp,8
...
mov     [ebp-4],eax     ;   x
mov     [ebp-8],eax     ;   z
...
sub     esp,N           ;   N=4*n
...
sub     esp,M           ;   M=4*m
...
mov     [ebp-4],eax     ;   по прежнему x
mov     [ebp-8],eax     ;   по прежнему z
                        ;   т. о. имеем синтаксический оверхед только для самих динамических массивов
...


Проверял без фанатизма, но первый взгляд показал, что именно так — вполне логично как по мне — поступает MSVC++ при использовании alloca (выделяет переменные известного размера до переменного участка и использует ebp даже при указании omit frame pointers). В общем никакой сложности и оверхеда, ну разве что frame pointer теперь не можем опустить.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.