Почему вы продолжаете мне рассказывать про строение аппаратного стека?
Да неужели?
Макроассемблер
А когда дело доходит до виртуальных машин, всё становится ещё сложнее.
struct stack
{
char *data;
struct stack *next;
};
В том, что на машинном коде я могу написать программу без call, без автоматических действий и прочего. Только тот минимум, который необходим. С тем оптимизациями, которые уместны или недоступны верхнему уровню.
Т.е. если бы вы писали на машинном коде, у вас бы программа работала бы быстрее, чем на ассемблере.
Одна команда выполняется за несколько тактов, состоит из нескольких микрокоманд, которые выполняются за 1 такт.
Обязательно. В противном случае, эта абстракция называлась бы по-другому.
Адреса регистров заранее известны
Получается, что оверхед по командам составляет минимум 2х, а по времени - минимум 4х.
Поэтому с этой точки зрения микрокод выполняется за дробное количество операций.
Он никак не привязан к тактам
Кстати, регистры - это тоже своего рода физическая абстракция, т.к. для процессора регистры являются такой же памятью, как и l1,l2,l3,ram,ПЗУ
Например, команда call вызывает процедуру, и транслируется в несколько инструкций (операций). Даже если подобные инструкции однозначны, они дают оверхед.
Не просто большой стек, а большой высоко утилизированный много фрагментированный (короче обычный) стек. Аналогично жёсткому диску, фрагментация замедляет работу.
чем больше стек, тем больше выполняется операций по работе с ним => тратится больше тактов процессора на несвязанные с программой действия => коэффициент утилизации падает.
Микроко́д — программа, реализующая набор инструкций процессора.
хранить большие переменные на стеке неэффективно
ulimit -s изменяет размер аппаратного стека для процесса