VM이 "스택 머신"또는 "시스템 등록"등이어야하는 이유는 무엇입니까?


48

(이것은 매우 새로운 질문입니다).

나는 가상 머신에 대해 조금 공부하고 있습니다.

많은 것이 물리적 또는 이론적 컴퓨터와 매우 유사하게 설계되었습니다.

예를 들어 JVM이 '스택 머신'이라는 것을 읽었습니다. 그 의미는 (그리고 내가 틀렸다면 나를 수정하십시오) 그것이 모든 '임시 메모리'를 스택에 저장 하고이 스택에서 모든 opcode에 대해 작업을 수행한다는 것입니다.

예를 들어, 소스 코드 2 + 3는 다음과 유사한 바이트 코드로 변환됩니다.

push 2
push 3
add

내 질문은 이것입니다 :

JVM은 아마도 C / C ++ 등을 사용하여 작성되었을 것입니다. 그렇다면 왜 JVM이 다음 C 코드를 실행하지 2 + 3않습니까? ..? 내 말은, 왜 실제 컴퓨터처럼 스택이나 다른 VM '레지스터'가 필요한가?

기본 물리적 CPU가이 모든 것을 처리합니다. VM 작성자가 VM이 프로그래밍 된 언어로 '일반적인'명령어를 사용하여 해석 된 바이트 코드를 단순히 실행하지 않는 이유는 무엇입니까?

실제 하드웨어가 이미이를 위해 VM에서 하드웨어를 에뮬레이션해야하는 이유는 무엇입니까?

다시 한 번, 아주 새로운 질문입니다. 당신의 도움을 주셔서 감사합니다


5
비가 상 머신이 기반으로 하는 것을 고려 했습니까 ?

5
@MichaelT 실제 기계를 의미합니까?
Aviv Cohn 2016 년

물론 대부분의 Javascript VM은 스택 머신이 아니거나 레지스터 시스템이 아닙니다 .V8 / IonMonkey / Chakra 등은 Javascript를 구현하는 VM입니다. "VM"은 디자이너가 원하는 모든 언어를 구현할 수있는 인터프리터 또는 JIT 컴파일러 일뿐입니다.
Billy ONeal 5

@BillyONeal 예를 들어 어떤 언어의 VM을 작성하고 C로 작성하는 경우 : VM은 bytcode 행 'print "hi"'를 구문 분석하고 실행합니다 printf("hi");. 이것이 VM으로 간주됩니까? '스택'또는 '레지스터'등이 없습니다.
Aviv Cohn

@ Prog : 맞습니다.
Billy ONeal

답변:


51

가상이든 아니든 기계에는 계산 수행 방법을 설명하는 계산 모델이 필요 합니다. 정의에 따라 계산하자마자 일부 계산 모델을 구현합니다. 그렇다면 VM에 어떤 모델을 선택해야합니까? 물리적 시스템은 하드웨어에서 효과적이고 효율적으로 수행 할 수있는 기능으로 제한됩니다. 그러나 알다시피 가상 머신에는 그러한 제약이 없으며 임의로 고급 언어를 사용하는 소프트웨어로 정의됩니다.

사실, 여러분이 설명한대로 높은 수준의 가상 머신이 있습니다. 이를 프로그래밍 언어라고합니다 . 예를 들어, C 표준은 C 프로그램의 동작 방식을 설명하는 소위 "C 추상 머신"에 대한 모델을 정의하고, 규칙에 따라 C 컴파일러 (또는 인터프리터)를 확장하는 방식 (확장)으로 정의하기 위해 대부분의 페이지를 전용으로 사용합니다. 행동해야합니다.

물론 일반적으로 가상 머신이라고 부르지는 않습니다. VM은 일반적으로 하드웨어에 더 가깝고 직접 프로그래밍되지 않고 효율적으로 실행되도록 설계된 것이 아닙니다. 이 선택 바이어스는 높은 수준의 코드를 실행 하기 때문에 높은 수준의 작성 가능한 코드 (예 : 설명하는 것과 같은)를 허용하는 것이 VM으로 간주되지 않음을 의미 합니다.

그러나 요점을 알기 위해 여기에 바이트 바이트 컴파일러가 대상으로하는 VM을 레지스터 기반 등으로 만들어야하는 몇 가지 이유가 있습니다. 스택 및 레지스터 머신은 매우 간단합니다. 각 명령어에 대한 일련의 명령어, 일부 상태 및 의미가 있습니다 (State-> State 함수). 복잡한 트리 축소 및 운영자 우선 순위가 없습니다. 구문 분석, 분석 및 실행은 최소한의 언어 (구문 설탕이 컴파일 됨)이며 인간이 아닌 기계가 읽도록 설계 되었기 때문에 매우 간단합니다.

대조적으로, 가장 간단한 C와 같은 언어를 파싱하는 것은 매우 어렵고, 유형 검사 및 전파, 과부하 해결, 기호 테이블 유지 관리, 문자열 식별자 해결 , 선형 텍스트를 우선 순위 중심 AST로 변환하는 등의 로컬이 아닌 분석이 필요합니다. , 등등. 인간에게는 자연 스럽지만 기계로 역 설계해야하는 개념을 기반으로합니다.

예를 들어 JVM 바이트 코드는에 의해 생성됩니다 javac. 사실상 사람이 읽거나 쓸 필요가 없으므로 기계 소비에 맞게 조정하는 것이 당연합니다. 인간을 위해 최적화했다면, JVM은 모든 시작에서 코드를 읽고, 분석하고, 분석 한 다음, 단순화 된 기계 모델과 유사한 중간 표현으로 변환 합니다 . 중간 사람을 잘라낼 수도 있습니다.


그래서 당신이 말하는 것은 스택의 명령어로 모든 것을 컴파일하는 것입니다 (즉 System.out.println("hi");, 스택 int a = 7의 명령어로 컴파일되거나 스택의 명령어로 컴파일되는 등)는 프로그램을 간단하고 효율적으로 실행하는 것입니까?
Aviv Cohn 2016 년

2
@Prog 기본적으로 그렇습니다. 그러나 실행뿐만 아니라 분석도 가능합니다. 프로그래밍 방식으로 수행되는 모든 것 .

그래도 왜 2 + 3컴파일 되는지 이해가되지 않습니다 push 2 push 3 add. 결국 add단계는 C 코드를 실행하여 JVM에 의해 실행 2 + 3됩니다. JVM 프로그래머가이를 수행하는 다른 방법은 없습니다. 로 컴파일 2 + 3하고 JVM이 C 코드를 2 + 3작성한다고 가정하면 (C로 작성되었다고 가정)?
Aviv Cohn

@Prog JVM 작성자는 2 + 3임의의 순서로 작업을 수행하는 모든 프로그램에서 JVM을 사용해야 하므로 JVM 소스 코드 만 작성할 수 없습니다 . C 소스 코드를 작성하고 C 구현을 연기하면 동일한 문제가 C 구현으로 푸시됩니다 (효율적으로 혼자서도 쉽게 수행 할 수 없음). 프로그램을 해석하고 JIT 컴파일 할 수 있도록 프로그램을 설명하는 일부 데이터 구조가 있어야하며 "사람이 읽을 수있는 소스 코드"는 위에서 설명한 이유로 데이터 구조를 엄선한 선택입니다.

7
@Prog 당신은 2 + 3의 특정 사례에 너무 집중 한 것 같습니다 a + b. 그런 다음 추가 할 값은에서 나오지 않으며 i.argument{1,2}지역 변수에서로드됩니다. 무엇에 대해 frobnicate(x[i]) + (Foo.bar() * 2)? 이 설계를 사용하면 add(의 int) 작업 이 하나만 있으며 추가 계산 방법과 독립적으로 작동합니다. 또한, 추가 명령 에만 정수 리터럴은 무의미 : 그것의 결과는 단지뿐만 아니라 사전에 계산 될 수있다 (즉, 대신 add(2,3)이 있어야한다 push(5)).

20

이 답변은 JVM에 중점을 두지 만 실제로 모든 VM에 적용됩니다.

실제 하드웨어가 이미이를 위해 VM에서 하드웨어를 에뮬레이션해야하는 이유는 무엇입니까?

그렇지는 않지만 VM을 훨씬 단순하고 이식 가능하게 만듭니다. 하드웨어를 에뮬레이트하는 VM은 하드웨어 CPU와 동일한 계산 모델을 사용할 수 있습니다.

특히 JVM은 이식성을 염두에두고 제작되었으며, 실제로는 하드웨어로 구현할 수 있도록 제작되었습니다 (오늘은 믿기 어려울 수 있지만 Java기원은 임베디드 세계에있었습니다. 특히 대화 형 TV 용 컨트롤러 ).

이와 같은 목표가 있다면 실제 머신 코드로의 변환이 더 쉽고 빨라지므로 VM은 가능한 한 물리적 머신에 가깝게 작동하는 것이 바람직합니다. 이론적으로 VM의 opcode가 있으면 프로그램이 실제로 실행되는 CPU의 opcode로 변환하기 만하면됩니다. 실제로 그것은 그렇게 간단하지 않습니다.

내 말은 왜 실제 컴퓨터처럼 스택이나 다른 VM '레지스터'가 필요한가?

스택 기반 가상 머신 모델을 사용하면 레지스터 머신과 스택 머신 모두로 쉽게 전송할 수 있다는 장점이 있지만 그 반대의 경우도 마찬가지입니다. 레지스터 기반 VM은 레지스터 수, 레지스터 크기 등을 가정해야합니다. 스택 머신에서는 이러한 가정이 필요하지 않습니다.

기본 물리적 CPU가이 모든 것을 처리합니다. VM 작성자가 VM이 프로그래밍 된 언어로 '일반적인'명령어를 사용하여 해석 된 바이트 코드를 단순히 실행하지 않는 이유는 무엇입니까?

이것이 그러한 VM이하는 일이며 바이트 코드를 해석합니다. 심지어 JVM조차도 적어도 JIT (Just-in-Time)가 시작되기 전에 실제로 그렇게합니다 : 바이트 코드를 해석하고 JVM이 작성된 언어 (일반적으로 C 또는 C ++이지만 명령문이 하나 있음)로 명령문을 실행합니다 JavaScript에서 Doppio ). 그러나 이러한 명령문조차도 컴파일러에 의해 기계 코드로 변환되었으며 실제로 Java 컴파일러가 생성하는 것과 매우 유사합니다. 즉, 레지스터와 스택을 사용하여 작업을 수행합니다. "통역 된"대 "컴파일 된"언어의 사용은 이 시점에서 다소 흐려 집니다.


물론, 소프트웨어로 구현 될 수있는 것은 하드웨어로 구현 될 수있다. 또한 현재 JVM (핫스팟)은 JIT 컴파일러 입니다. JVM이 작성된 언어로 명령문을 실행 하지 않습니다 . 그렇게하면 Java가 끔찍하게 수행되어 오늘날처럼 플랫폼 근처에있을 수 없습니다. . (자, 대부분의 Javascript 구현이 더 빠를 것입니다)
Billy ONeal

2
@BillyONeal "시간에 맞춰 메소드별로 메소드를 컴파일하는 대신 Java HotSpot VM은 즉시 인터프리터를 사용하여 프로그램을 실행하고 코드가 실행될 때 코드를 분석하여 프로그램의 중요한 핫스팟을 감지합니다. "핫 스팟 에서 글로벌 네이티브 코드 최적화 프로그램." oracle.com/technetwork/java/whitepaper-135217.html#2 , "핫 스팟 감지"섹션 에서 인용
miraculixx

예. "네이티브 코드 옵티 마이저"== JIT 컴파일. JITing에서 거의 사용하지 않는 것을 피하기 위해 "뜨거운"것처럼 보이지 않는 코드에 대한 인터프리터 단계가 있습니다. 그렇다고 JITing이 전혀 이루어지지 않았다는 의미는 아닙니다.
Billy ONeal

대답 해줘서 고마워. 내가 당신의 대답에서 수집 한 것은 VM에서 하드웨어를 에뮬레이션하는 이유 (일명 '스택'또는 '레지스터'등)는 나중에 바이트 코드 또는 소스 코드를 실제 머신 코드로 쉽게 컴파일 할 수 있기 때문입니다. 물리적 CPU. 그러나 그 외에도 VM의 하드웨어를 에뮬레이션하여 얻을 수있는 것이 있습니까? 실제로 VM을 설계하는 누군가가 실제로 소프트웨어에 관해 이야기 할 때 왜 '스택 머신'또는 '시스템 등록'등의 관점에서 생각하는지 이해하지 못합니다. 뭔가 빠졌습니까?
Aviv Cohn 2016 년

@Prog Ok, X라는 프로그래밍 언어가 있습니다. 어떻게 프로그램을 실행할까요? 소스를 해석하거나 기계 코드로 컴파일하거나 중간 코드로 컴파일 할 수 있습니다. 이제 다른 프로그래밍 언어 인 Y가 있고 X를 사용하여 구현하려고합니다. 두 구현이 모두 인터프리터 인 경우 Y의 인터프리터가 X의 인터프리터에서 실행되므로 매우 느립니다.
18446744073709551615

11

VM이 "스택 머신"또는 "시스템 등록"등이어야하는 이유는 무엇입니까?

그들은하지 않습니다. 가상 머신이 필요한 경우 가상 머신 일 수 있습니다.

기존 가상 머신은 다음과 같은 상황에 대한 솔루션으로 등장했습니다. 정말 훌륭한 아이디어가 떠 올랐습니다. 새로운 프로그래밍 언어를 발명했습니다! 그러나 코드를 생성해야합니다. (정말 지루한 작업입니다!) 그러나 i8086 코드는 추악하기 때문에 생성하고 싶지 않으며 다른 모든 사람들이 Intel을 사용하고 있기 때문에 68k 코드를 생성하고 싶지 않습니다. VAX도 있지만 VAX가 없으며 컴퓨터 나 VAX 책도 없습니다. 따라서 물리적으로 존재하지 않는 일부 프로세서에 대한 코드를 생성하고 해당 프로세서를 소프트웨어로 구현합니다. 그 VM의 스펙은 논문의 장을 만들 것입니다. 이론적으로는 모든 프로세서의 원시 코드로 컴파일 할 수는 있지만 그럴 수는 없습니다.

반면에 "2 + 3"과 같은 표기법은 아마도 VM에서 미래에는 사용되지 않을 것입니다. 왜냐하면 무언가 실행되기 전에 많은 변환을 수행하기 때문입니다.


대답 해줘서 고마워. 따라서 귀하의 답변에서 수집 한 것은 실제 CPU를 에뮬레이트하는 VM을 설계하려는 동기는 나중에 실제 기계 코드로 컴파일하는 컴파일러를 쉽게 구현할 수 있기 때문입니다. 그러나 그 외에- '스택 머신'또는 '등록 머신'등의 관점에서 VM을 설계 할 때 어떤 이점이 있습니까?
Aviv Cohn 2016 년

1
레지스터에는 이론과 디버깅이 모두 필요한 레지스터 할당 알고리즘이 필요합니다. 스택 머신 (es-zero and one)은 데이터를 스택에 배치 할 수 있습니다. OTOH 하드웨어는 일반적으로 가변 크기 스택이 아닌 제한된 양의 레지스터를 구현합니다. 따라서 스택은 소프트웨어에서 쉬워지고 레지스터는 하드웨어에서 쉬워 지므로 아마도 조금 더 빠릅니다.
18446744073709551615

-2

요청 된 실제 질문에 대답합니다. "가상 머신"이라는 용어는 모든 소프트웨어 / 하드웨어가 시뮬레이션 / 에뮬레이트됨을 의미합니다. 기본 소프트웨어 / 하드웨어를 사용하여 명령어를 실행하는 경우 VM이없고 컴파일러 / 인터프리터가있는 것입니다.


이것은 단지 당신의 의견입니까, 아니면 어떻게 든 백업 할 수 있습니까?
gnat

@Kyrelel 사실이 아닙니다. "ALL"하드웨어는 "system"또는 "full"VM에서 에뮬레이션됩니다. 모든 VM이 가득 찬 것은 아닙니다. 예를 들어, 하드웨어가 에뮬레이션되지 않더라도 BSD VM 계층의 이름은 "가상 머신"입니다.
Netch

나는 그 용어가 반드시 용어에 관한 것이라고 생각하지는 않지만 가상 머신이 실제 하드웨어에 의해 이미 처리 된 것처럼 보이는 기능을 구현하는 이유
Ryan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.