| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
Эта короткая статья посвящена виртуальным машинам, их типам, их преимуществам и недостаткам. Несомненно, эта информация не нова, но мы рассмотрим виртуальные машины с позиции их создания, а не использования (а таких статей на порядок меньше).
VMs.
Нет, VMs!=VMS, VMs==Virtual Machines. Как известно, виртуальные машины делятся на основные 3 класса: стековые, регистровые, трехадресные. Особенности этих машин ясны прямо из названий. Естественно, существует огромное количество машин, полученных с помощью "скрещивания" представителей основных классов. Если есть необходимость реализовывать виртуальную машину, нужно сначала точно определить необходимые характеристики, требовательность к быстродействию и т.д. Мы же покажем, на что нужно обратить внимание, делая выбор между основными типами машин.
a) стековые VMs
Вся работа производится через стек. Т.е., скажем, для сложения 2х чисел их нужно сначала положить в стек, а потом вызвать функцию сложения, которая произведет все необходимые действия и результат положит в стек. Этот тип машин обладает вполне приличным быстродействием, но при большом количестве последовательных вызовов таких функций быстродействие распыляется на работу со стеком. Например, дано выражение a*e+(b-c)/d
(постфиксная форма записи: a e * b c - d / +)
последовательность операций будет выглядеть так:
Команда |Действий со стеком |
--------+-------------------+
push a | 1 |
push e | 1 |
mul | 3 (2*pop+1*push) |
push b | 1 |
push c | 1 |
sub | 3 (-----//-----) |
push d | 1 |
div | 3 (-----//-----) |
add | 3 (-----//-----) |
--------+-------------------+
В итоге получаем, что на 9 команд мы имеем 17 действий со стеком, т.е. почти в 2 раза больше. Если вспомнить, что каждое действие со стеком не является атомарным, а занимает около 4 процессорных инструкций (безо всяких проверок, просто помещение или извлечение из стека), получаем, что программа на виртуальной машине будет выполняться, как минимум, в 6-8 раз медленнее. На самом деле, замедление будет еще большим, т.к. инструкции mul, div, sub, add виртуальной машины не будут атомарными (т.е. будут состоять из нескольких процессорных инструкций).
PUSH:
mov eax,stack_top
add [eax], 1
add eax,p_stack
mov [eax], value
б) регистровые VMs
Данные функциям передаются через регистры. Вроде бы, этот тип машин должен работать быстрее стековых (т.к. регистровые VMs очень похожи на "нормальные" вычислительные машины, на которых они исполняются), но в этом случае мы сталкиваемся с тем, что основная потеря в производительности будет приходиться на операции с регистрами. В физических вычислительных машинах регистровая память работает гораздо быстрее оперативной (поэтому, иногда ее называют сверхоперативной памятью). Мы имеем возможность хранить регистровую память только в оперативной памяти. Если бы удалось использовать регистры физической машины, можно было бы ускорить процесс исполнения программы. Но в данном случае время будет теряться на сохранение и восстановление значений физических регистров. Поэтому, как и в предыдущем случае большая детализация в разработке инструкций виртуальной машины ведет к существенной потере производительности.
в) трехадресные VMs
Очень интересный класс виртуальных машин. Большинство инструкций имеют 3 операнда: адрес первого аргумента, адрес второго аргумента, адрес результата. Из всех классов виртуальных машин трехадресные имеют самое низкое замедление (тем не менее, все равно существенное по причине неатомарности инструкций).
|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |