Вызываемый абонент сохраняет, когда вызывающий абонент передает использованные регистры?
-
03-07-2019 - |
Вопрос
В конструкции компилятора, почему вместо наличия механизма сохранения регистров вызывающего или вызывающего абонента не может вызывающий объект передать свой список используемых регистров (который он будет передавать в случае механизма сохранения вызывающего объекта) вызываемому, чтобы вызываемый мог сравнить его список используемых регистров в регистры, используемые вызывающей стороной.Тогда будут отправлены только те регистры, которые действительно необходимо отправить.Я что-то пропустил?
Решение
Это интересная идея.Я думаю, что есть две вещи, которые делают его менее привлекательным:
- В любом случае вызываемый объект должен зарезервировать место в стеке на случай худшего случая.
- Чтобы сделать его эффективным, вам потребуются специальные инструкции для одновременного хранения и загрузки наборов регистров.Такие инструкции были на Motorola 68000 (а может быть и на PowerPC), но они не пользовались популярностью.
Вот небольшое пояснение того, как это должно работать:Вы бы хотели, чтобы вызывающая сторона упаковала список в машинное слово в виде битового вектора.Тогда вам потребуется, чтобы вызываемый объект выполнял побитовую операцию со своим собственным списком и имел инструкцию, которая сохраняет все регистры, названные результирующим битовым вектором.
Поскольку вам придется зарезервировать место в стеке на случай худшего случая, вы не сильно сэкономите — на современном суперскалярном процессоре с нарушением порядка записи в одну и ту же строку кэша практически бесплатны.
Верно также и то, что если вы действительно хотите минимизировать количество загрузок и сохранений во время выполнения, вы просто используете все регистры сохранения вызывающего абонента.Эта стратегия также позволяет очень дешево создавать исключения и упреждающее переключение потоков, а множество компиляторов (например, OCaml) используйте его по этой причине.Регистры сохранения вызываемого абонента — это своего рода хак, позволяющий сократить размер кода для инструкций сброса и перезагрузки.Они работают во многих ситуациях и экономят место, поскольку число сайтов вызовов намного превышает количество определений процедур (в среднем процедура содержит несколько вызовов).
Для получения дополнительной информации о компромиссах между регистрами сохранения вызывающего абонента и регистрами сохранения вызываемого абонента см. хорошая статья Джека Дэвидсона и Дэвида Уолли.
Другие советы
это очень неэффективно...вам нужно будет проанализировать список (для каждой функции!), что совершенно не нужно.