Вопрос по java – Преимущества стековой архитектуры инструкции JVM
=================================================================

Почему виртуальная машина Java была разработана без регистров для хранения промежуточных значений данных? Вместо этого все работает в стеке. есть ли какое-то конкретное преимущество наличия основанной на стеке архитектуры вместо регистра?

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

Только во время выполнения JVM действительно знает доступные регистры и другие аппаратные средства. Тогда JIT-компилятор может (и будет) оптимизировать их в зависимости от обстоятельств.



стек, чем набор виртуальных регистров. Если у хост-машины есть стек, как и у всех, делать нечего, и если у него есть регистры, вы все равно можете использовать их для других задач: временных и т. Д. Если, с другой стороны, у хост-машины нет регистров только стек, и вы разрабатываете свою виртуальную машину на основе регистров, у вас есть серьезная проблема с реализацией, так как вам приходится использовать собственный стек таким образом, чтобы это мешало его использованию в качестве виртуального стека.



Предположение о существовании стека выражений не лучше предположения, чем существование регистров. Как правило, машины регистрации не могут напрямую выполнять коды операций стека, а машины стека не могут напрямую выполнять коды операций стека. Они должны быть нанесены на карту.

EJP говорит"If the host machine has a stack, **as they all do, there is nothing to do**", Это ложное утверждение. Предположение, что все машины имеют стеки, способные выполнять вычисления, демонстрирует путаницу в том, чем на самом деле является стековая машина.

A stack based machine has an instruction set with implicit operands on the top
of an "expression stack". Not a general purpose stack. A general purpose stack does not a stack machine make. They can save/restore values. All platforms have that. But they can't execute computations.
A register based machine executes typical opcodes with operands that are explicit, virtual
registers, encoded in the instruction stream. Those VMs still have general purpose stacks and opcodes to save and restore registers. You can't map stack calculation ops to a data stack. The core instruction set's operands are registers, memory addresses or immediates (encoded within opcode).

Так что, безусловно, больше, чем «ничего не делать» отображать коды операций одной машинной архитектуры в другую. Если у вас нет чипа с собственным ускорением кода операции Java, вам лучше этого не предполагать.

Я не спорю с тем, что стековая машина - хороший выбор для мобильности. Я говорю, что «есть чем заняться» отобразить инструкции из стека в регистрor регистр-стека. Оба возможны.

Тем не менее, много разговоров носит академический характер. ВpracticeВ 2014 году распространенной платформой является регистрация. Даже основанные на стеке «процессоры» часто это мягкие чипы, реализованные в верхней части регистрационного чипа. Посмотрите спецификацию Java Card 3, посмотрите на реализации и выясните, какие процессоры фактически используются. Я оставлю это как упражнение.

Если мы не проектируем виртуальную машину для очень конкретной платформы (например, нас попросили разработать JVM, которая будет когда-либо работать только на процессоре GreenSpaces, чего я не вижу), то я предполагаю, что контекст является общим приложением. Встраиваемые приложения, приставки, контроллеры прошивок, игрушки, даже смарт-карты. Для всего этого я вижу 8-32-битные процессоры, такие как ARM, либо используемые, либо доступные. Основная JVM написана на языке C. C позволяет проектировать интерпретатор с кодами операций виртуального стека или виртуального регистра. В 90-х годах было много дискуссий о стековых процессорах Java, которые напрямую поддерживают коды операций JVM. В 2014 году мы увидим эти реализации на аппаратном обеспечении на основе регистров или в качестве дополнительных инструкций, таких как Jazelle (ускорение Java) на ARM926EJ-S, где также есть регистры и поддержка набора команд ARM.

Заgeneral applicationвиртуальные машины на основе стеков, конечно же, на практике не соответствуют стекам. Все эти машины используют основанные на регистре первичные инструкции; и операции стека предназначены для сохранения и восстановления регистров или стека вызовов, без выполнения вычислений, логики или ветвления. Виртуальные машины стека JIT соответствуют собственному набору команд машины, независимо от того, является ли он набором стеков или регистров. С 1980 года практически каждая новая архитектура процессора была зарегистрирована, согласноHennessy And Patterson - "Computer Architecture A Quantitative Approach", Это означает наборы регистр-регистр, регистр-память или регистр-непосредственный регистр. Вы не можете добавить 2 значения в стек на компьютере, который не имеет добавления на основе стека. На x86 ваши коды операций на основе стека для операции ADD могут переводиться с:

```
push a
push b
add

```

в собственный регистрационный код:

```
mov eax, [addra]
mov ebx, [addrb]
add eax, ebx

```

Во-вторых, независимо от того, является ли поток кода операции стеком или регистром, JIT может скомпилировать его в собственный код. Таким образом, выбор модели виртуальной машины - это просто программная модель. Реестр машин такой же виртуальный. Они не кодируют какую-либо информацию о собственном регистре, регистры в кодах операций являются виртуальными символами.

Теперь, когда разрабатывался Java, мы думали о совместимости небольших операционных кодов и 8-битных процессоров. Коды операций на основе стека меньше, чем коды операций регистрации. Так что это имело смысл. Я уверен, что где-то читал, что это была одна из основных причин, по которой Джеймс Гослинг выбрал его для Oak (оригинальное название для Java), помимо простоты. У меня просто нет ссылки на руку. В этом я согласен с P & # xE9; ter T & # xF6; r & # xF6; k.

There are observable benefits to stack opcode. The codestreams are often smaller / denser. Regarding the JVM and CLR, observed stackbased bytecodes can be 15-20% smaller than other machines. Stack bytecodes can be easily encoded in <= 8 bits. (Forth machines can have as few as 20 or so opcodes). The opstream is easier to encode/decode. Try writing an assembler or disassembler for Java then for x86.
There are observable benefits to register opcode. Fewer opcodes to encode an expression = better IPC = less high level branching in the interpreter. It can also directly map a small number of registers (8 to 16) to virtually every modern processor. Use of registers achieves much higher throughput due to better cache locality of reference. On the contrary, stack machines use a lot of memory bandwidth.

В виртуальных машинах регистр байт-кодов часто использует большой набор виртуальных регистров, для чего требуются байт-коды большего размера. На большинстве реальных аппаратных средств регистры обычно кодируются от 3 бит (Intel x86) до 5 бит (Sparc), поэтому плотность может отличаться от виртуальной машины к виртуальной машине или от процессора к процессору или от виртуальной машины к процессору. Dalvik использует от 4 до 16 бит для представления регистров, тогда как Parrot использовал 8 бит на регистр во всех кодах операций (по крайней мере, я использовал формат байт-кода v2). Dalvik достигает лучшей средней плотности. Основываясь на моем опыте их создания, трудно создать регистрационную машину общего назначения в пределах 8-битного байт-кода, если вы строго не придерживаетесь примитивов и не используете небольшой регистровый файл. Это может показаться не интуитивным, но обычно один код операции имеет несколько кодировок с различными типами регистров.

И последнее замечание: большая часть оптимизации программного ядра потенциально выходит за рамки, когда JIT входит в картину.

Основное исключение, которое я принимаю в качестве аргумента, что стековые машины лучше сопоставляются с аппаратным обеспечением, - это то, что он игнорирует, где работает JVM и / или куда движется технология. За исключением Чака Мура, я не знаю никого, кто бы разрабатывал стековые процессоры (IGNITE и GreenSpaces GA144), и большинство новых разработок - это регистратор. Аргументы в пользу стековых машин носят преимущественно академический характер. Для каждого аргумента 8-битного процессора стека я могу показать вам несколько машин с регистрами (Hitachi H8 с регистрами, ARM926 с регистрами, Intel 8051) с компилятором C. Скорее всего, вы будете писать в Forth на чистом стековом процессоре, чем на Java. Для новой платформы более целесообразно использовать дешевый процессор ARM, где есть компиляторы C, полная JVM и т. Д. Эти наборы команд запуска регистров.

ARM926 / ARM926EJ-S - [http://www.arm.com/products/processors/classic/arm9/arm926.php](https://www.arm.com/products/processors/classic/arm9/arm926.php)
H8 - [http://en.wikipedia.org/wiki/H8\_Family](https://en.wikipedia.org/wiki/H8_Family)
Так что, если это правда? Это имеет значение? Мое мнение, основанное на моем опыте, "не так, как думают люди". Помните, что байт-код является лишь промежуточным представлением. Чисто интерпретируемое ядро машины часто является трамплином, мостом, отказоустойчивым ядром по умолчанию. Конечным пунктом назначения является возможная версия 2 с JITter для собственной производительности. Таким образом, точка зрения, которой придерживаются многие, кто сделал это один или два раза, состоит в том, что имеет смысл сохранить ядро настолько простым, насколько это возможно, и перейти к JIT, тратя на него 90% оптимизации. Любые напрасные усилия по настройке перехваченного ядра можно рассматривать как преждевременную оптимизацию. Если, с другой стороны, вы не планируете JITter, или JIT нецелесообразен из-за ограничений памяти, затем оптимизируйте виртуальное ядро или внедрите виртуальную машину на чипе.