VM'lerin neden “yığın makineleri” veya “kayıt makineleri” vb olması gerekiyor?


48

(Bu son derece acemi bir soru).

Sanal Makineler hakkında biraz çalışıyorum.

Birçoğunun fiziksel veya teorik bilgisayarlara çok benzer şekilde tasarlandığı ortaya çıktı.

Örneğin JVM'nin bir 'yığın makinesi' olduğunu okudum. Bunun anlamı (ve eğer hatalıysam beni düzelt) tüm 'geçici hafızasını' bir yığında depolar ve bu yığında tüm işlem kodları için işlemler yapar.

Örneğin, kaynak kodu 2 + 3şuna benzer bir bytecode'a çevrilecektir:

push 2
push 3
add

Sorum şu:

JVM'ler muhtemelen C / C ++ ve benzerleri kullanılarak yazılmıştır. Öyleyse, JVM neden şu C kodunu çalıştırmıyor: 2 + 3..? Yani, neden bir yığına veya fiziksel bilgisayardaki gibi diğer sanal makinelerin 'kayıt defterlerine' ihtiyaç duyuyor?

Temel fiziksel CPU bunların hepsini halleder. VM yazarları neden çevrilen bytecode'u VM'nin programlandığı dilde 'olağan' talimatlarla basitçe çalıştırmıyor?

Sanal donanım zaten bizim için bunu yaptığında, neden VM'lerin donanımı taklit etmesi gerekiyor?

Yine, çok yeni başlayanlar-sorular. Yardımınız için teşekkürler


5
Sanal olmayan makinelerin neye dayandığını düşündünüz mü ?

5
@MichaelT Fiziksel makineleri mi kastediyorsunuz?
Aviv Cohn

Tabii ki, çoğu Javascript VM yığın makineleri veya kayıt makineleri değildir - V8 / IonMonkey / Çakra / vb. Javascript uygulayan VMlerdir. Bir "VM", tasarımcının istediği herhangi bir dili uygulayabilen bir tercüman veya JIT derleyicisidir.
Billy ONeal

@BillyONeal Örneğin, eğer bir dil için bir VM yazıyorsam ve onu C'ye yazıyorsam: VM, bytcode satırını "print" hi "yazıp ayrıştırır ve yürütür printf("hi");: bu bir VM olarak kabul edilir mi? Hiçbir "yığın" veya "kayıt" ve / veya hiçbir şeye sahip değildir.
Aviv Cohn

@Prog: Evet, doğru.
Billy ONeal

Yanıtlar:


51

Sanal olan veya olmayan bir makinede, üzerinde hesaplamanın nasıl yapıldığını açıklayan bir hesaplama modeli gerekir. Tanım olarak, hesaplar tamamlamaz, bazı hesaplama modellerini uygular. O zaman soru şudur: VM için hangi modeli seçmeliyiz? Fiziksel makineler, donanımda etkin ve verimli bir şekilde yapılabilecekler ile sınırlandırılmıştır. Ancak, not ettiğiniz gibi, sanal makinelerin böyle bir kısıtlaması yoktur, bunlar keyfi bir şekilde yüksek seviyeli diller kullanılarak yazılımda tanımlanır.

Aslında, tarif ettiğiniz gibi yüksek seviyeli sanal makineler var. Bunlara programlama dilleri denir . Örneğin, C standardı, sayfalarının büyük bölümünü, C programlarının nasıl davrandığını açıklayan "C abstract machine" adı verilen bir model tanımlamaya, ve (uygun olduğu gibi) C derleyicisinin (veya yorumlayıcısının) nasıl uygun olduğunu açıklamaya yönelik bir model tanımlamaya adamıştır. davranmalı.

Tabii ki, biz genellikle buna sanal makine demiyoruz. Bir VM genellikle, doğrudan programlanması amaçlanmayan, verimli bir şekilde yürütülmesi amaçlanan, donanıma daha yakın, daha düşük seviyeli bir şey anlamına gelir. Bu seçim önyargısı, üst düzey beste edilebilir kodu (tanımladığınız gibi) kabul eden bir şeyin bir VM olarak kabul edilmeyeceği anlamına gelir çünkü yüksek düzeyli kod yürütür.

Ancak bu noktaya gelmek için, burada bir VM (gibi, bir bytecode derleyici tarafından hedeflenen bir şey) kayıt tabanlı veya benzeri bir hale getirmek için bazı nedenler. İstif ve kayıt makineleri son derece basittir. Her komut için bir talimatlar dizisi, bazı durumlar ve anlamlar vardır (bir fonksiyon - Durum -). Karmaşık ağaç azalması yok, operatör önceliği yok. Ayrıştırma, analiz etme ve yürütme çok basittir, çünkü asgari bir dildir (sözdizimsel şeker derlenir) ve insan tarafından okunmak yerine makine tarafından okunacak şekilde tasarlanmıştır.

Buna karşılık, en basit C-benzeri dilleri ayrıştırmak oldukça zordur ve yürütmek, türleri kontrol etmek ve yaymak, aşırı yükleri çözmek, bir sembol tablosunu korumak, dize tanımlayıcılarını çözmek , doğrusal metni öncelikli bir AST'ye dönüştürmek gibi yerel olmayan analizler gerektirir. , ve bunun gibi. İnsanlara doğal gelen, ancak makineler tarafından özenle tersine çevrilmiş olması gereken kavramlar üzerine kuruludur.

Örneğin JVM bayt kodu yayılır javac. Neredeyse hiç bir zaman insanlar tarafından okunması veya yazılması gerekmez, bu yüzden onu makineler tarafından tüketime yönlendirmek doğaldır. İnsanlar için optimize ettiyseniz, JVM hemen her başlangıçta kodu okur, ayrıştırır, analiz eder ve sonra yine de böyle basitleştirilmiş bir makine modeline benzeyen bir ara gösterime dönüştürürdü . Orta adamı da kesebilir.


Yani söylediğiniz şey, her şeyi yığındaki yönergelere derlemenin (yani System.out.println("hi");, bir yığındaki int a = 7bir talimat için derlendiğinde, yığındaki bir talimat için derlendiğinde vb.) Programın yürütülmesini basit ve daha verimli hale getirmesidir.
Aviv Cohn

2
@Prog Temelde, evet. Ama sadece yürütme değil, aynı zamanda analiz. Programlı olarak yapılan her şey .

Yine de neden 2 + 3derlendiğini anlamıyorum push 2 push 3 add. Sondaki addadım, C kodunu çalıştırarak yine de JVM tarafından yürütülür 2 + 3. JVM programcılarının bunu yapması için başka bir yol yoktur. Neden 2 + 3derlemiyorsunuz ve JVM hemen C kodunu 2 + 3(C ile yazılmış olduğu varsayılarak) hemen çalıştırsın mı?
Aviv Cohn

@Prog JVM yazıcısı 2 + 3JVM kaynak kodunu yazamaz çünkü JVM herhangi bir sırada herhangi bir işlem yapan herhangi bir programla çalışmak zorundadır. C kaynak kodunun oluşturulması ve bir C uygulamasının ertelenmesi, aynı sorunu C uygulamasının içine itmektedir (ve verimli bir şekilde tek başına kolayca yapılamaz). Programı açıklayan bazı veri yapıları olmalıdır, böylece yorumlanabilir ve JIT derlenebilir ve "insan tarafından okunabilir kaynak kodu" yukarıda belirtilen sebeplerden dolayı çok çeşitli bir veri yapısı seçeneğidir.

7
Sen de 2 + 3 Peki belirli durumları odaklanmış görünüyor @Prog a + b? Sonra eklenecek değerler gelmez i.argument{1,2}, yerel değişkenlerden yüklenirler. Ne hakkında frobnicate(x[i]) + (Foo.bar() * 2)? Bu tasarımı kullanarak, yalnızca bir addişlem var (çünkü int) ve eklerin nasıl hesaplandığından bağımsız olarak çalışır. Ayrıca, yalnızca tamsayı değişmezleri ekleyen bir komut anlamsız olacaktır: Sonucu önceden hesaplanabilir (yani bunun yerine add(2,3)olmalıdır push(5)).

20

Bu cevap JVM'ye odaklanır, ancak aslında herhangi bir VM için geçerlidir.

Sanal donanım zaten bizim için bunu yaptığında, neden VM'lerin donanımı taklit etmesi gerekiyor?

Onlar yapmazlar, ancak VM'yi çok daha basit ve taşınabilir yapar: Donanımı taklit eden bir VM, herhangi bir donanım CPU'su ile aynı hesaplama modelini kullanabilir.

Özellikle JVM taşınabilirlik düşünülerek inşa edildi, aslında donanımda bile uygulanabilecek şekilde inşa edildi (bugün inanması zor olabilir, ama Java'nın kökeni gömülü dünyadaydı - özellikle de etkileşimli televizyon kontrolörleri. ).

Böyle bir hedefiniz varsa, VM'nin mümkün olduğunca fiziksel bir makineye yakın çalışması istenir, çünkü gerçek makine koduna çevirmek daha kolay ve dolayısıyla daha hızlı hale gelir. VM'nin kodlarına sahip olduğunuzda teoride, yapmanız gereken tek şey programın gerçekten çalıştığı CPU'nun kodlarına çevirmektir. Uygulamada tam olarak bu kadar basit değil.

Yani, neden bir yığına veya fiziksel bilgisayardaki gibi diğer sanal makinelerin 'kayıt defterlerine' ihtiyaç duyuyor?

Bir yığın tabanlı sanal makine modelinin kullanılması, hem kayıt hem de yığın makinelerine kolayca aktarılabileceği avantajına sahiptir, bunun tersi de mutlaka doğru değildir. Kayıt tabanlı bir VM'nin kayıt sayısı, kayıtların boyutu vb. Hakkında varsayımlarda bulunması gerekir. Bir yığın makinesinde böyle bir varsayım gerekli değildir.

Temel fiziksel CPU bunların hepsini halleder. VM yazarları neden çevrilen bytecode'u VM'nin programlandığı dilde 'olağan' talimatlarla basitçe çalıştırmıyor?

Bu VM'lerin yaptığı budur, bytecode'u yorumlarlar. Hatta JVM bile, en azından JIT (tam zamanında) devreye girmeden önce: bayt kodlarını yorumlar ve JVM'nin yazıldığı dilde yapılan ifadeleri çalıştırır (tipik olarak C veya C ++, ancak bir tane bile vardır). JavaScript, Doppio ). Bununla birlikte, bu tür ifadelerin bile bir derleyici tarafından makine koduna çevrildiğini ve aslında Java derleyicisinin ürettikleriyle çok benzer göründüğünü, yani işlerini gerçekleştirmek için kayıtları ve yığını kullandıklarını unutmayın. "Yorumlanmış" vs "derlenmiş" dillerin kullanımının bu noktada biraz bulanıklaştığını unutmayın .


Elbette, yazılımda uygulanabilecek herhangi bir şey, donanımda da uygulanabilir. Ayrıca, şu anda JVM (hotspot) bir JIT derleyicisi - bu mu değil JVM yazılmış dilde ifadeleri çalıştırmak Öyle olsaydı, Java korkunç performans göstereceğini ve bugün olduğu gibi canlı bir platform olarak hiçbir yerde yakın olacaktır. . (Cehennem, çoğu Javascript uygulaması daha hızlı olurdu)
Billy ONeal

2
@BillyONeal "Metotla derleme yönteminden ziyade, tam zamanında, Java HotSpot VM programı derhal bir tercüman kullanarak çalıştırır ve programdaki kritik sıcak noktaları saptamak için çalıştığı gibi kodu analiz eder. Ardından, sıcak noktalarda global yerel kod eniyileyici. "alıntı oracle.com/technetwork/java/whitepaper-135217.html#2 ," Hot Spot Detection "bölümünden
miraculixx

Evet. "Yerel kod iyileştirici" == JIT derlemesi. JITing'in nadiren kullanılan şeyleri önlemek için kod için "sıcak" görünmeyen bir tercümanlık aşaması vardır. Ancak bu, hiçbir JİT işleminin yapılmadığı anlamına gelmez.
Billy ONeal

Cevapladığınız için teşekkürler. Cevabınızdan topladığım şey, VM'deki donanımı taklit etmenin nedenlerinin (aka 'yığınlar' veya 'kayıtlar' vb.) Nedeninin daha sonra bayt kodunu veya kaynak kodunu, bir makinenin gerçek makine koduna derlemesini kolaylaştırmasıdır. fiziksel işlemci. Ancak bunun dışında - bir VM'deki donanım taklit eden herhangi bir şey var mı? Aslında bir VM tasarlayan birinin gerçekte yazılımdan bahsederken neden “yığın makinesi” veya “kayıt makinesi” gibi düşüneceğini anlamıyorum. Bir şey mi eksik?
Aviv Cohn

@Prog Tamam, bir programlama diliniz var, X deyin. Programlarını nasıl çalıştıracaksınız? Kaynağı yorumlayabilir veya makine koduna derleyebilir veya ara kodda derleyebilirsiniz. Şimdi, başka bir programlama dili, Y var ve onu X kullanarak uygulamak istiyorum. Her iki uygulama da tercüman ise, X'in tercümanı üzerinde çalışan Y'nin tercümanına sahip olacaksınız ve bu çok yavaş olacaktır.
18446744073709551615

11

VM'lerin neden “yığın makineleri” veya “kayıt makineleri” vb olması gerekiyor?

Onlar yapmıyor. Sanal bir makineye ihtiyacınız varsa, herhangi bir şey olabilir.

Mevcut sanal makineler aşağıdaki gibi durumlara çözüm olarak ortaya çıktı: Kafama çok parlak bir fikir geldi, yeni bir programlama dili icat ettim! Ama kod üretmem gerekiyor. (Ne sıkıcı bir iş!) Ama i8086 kodu üretmek istemiyorum çünkü bu çok çirkin ve 68k kodu oluşturmak istemiyorum çünkü herkes Intel kullanıyor. Ayrıca bir de VAX var, ama ne bir VAX’e, ne bir bilgisayara ne de bir VAX kitabına sahip değilim. Bu nedenle fiziksel olarak bulunmayan bazı işlemciler için kod üreteceğim ve bu işlemciyi yazılımda uygulayacağım. Bu VM'nin tezi tezimde bir bölüm oluşturacak. Teorik olarak, herhangi bir işlemcinin yerel koduna derlemek mümkün olacak, ama bu ben olmayacağım.

Öte yandan, "2 + 3" gibi gösterimler önceden tahmin edilebilir bir gelecekte VM'ler tarafından kullanılmayacak çünkü bir şey yürütülmeden önce çok fazla dönüşüm yapılması anlamına geliyor.


Cevapladığınız için teşekkürler. Cevabınızdan topladığım şey, fiziksel CPU'ları taklit eden bir VM tasarlama motivasyonunun, daha sonra gerçek makine kodunu derleyen derleyicilerin uygulanmasını kolaylaştırmasıdır. Ancak bunun dışında - bir “yığın makinesi” veya “kayıt makinesi” vb. Açısından bir VM tasarlamanın avantajları var mı?
Aviv Cohn,

1
Kayıtlar hem teori hem de hata ayıklama gerektiren kayıt tahsisi algoritmaları gerektirir. Bir yığın makinesi (özellikle bir sıfır operandlı) veriyi yığına yerleştirebilir. OTOH, donanım genellikle değişken boyutlu bir yığından ziyade sınırlı miktarda kayıt uygular. Böylece yığınlar yazılım için daha kolaydır, kayıtlar donanım için daha kolaydır ve bu nedenle muhtemelen biraz daha hızlıdır.
18446744073709551615

-2

Sorulan asıl soruyu cevaplamak için. "Sanal MAKİNE" terimi, TÜM yazılım / donanımın simüle edildiğini / taklit edildiğini belirtir. Talimatları uygulamak için ilgili yazılımı / donanımı kullanıyorsanız, bir VM cihazınız yoktur, bir derleyiciniz / tercümanınız vardır.


Bu sadece senin fikrin mi, yoksa bir şekilde mi destekleyebilirsin?
tatarcık

@Kyrelel doğru değil. "ALL" donanımı "sistem" veya "tam" VM'de öykünüyor. Tüm VM'ler dolu değil. Örneğin, BSD VM katmanı donanım orada taklit edilmemesine rağmen "sanal makine" olarak adlandırılıyor.
Netch

Sorunun zorunlu olarak terminoloji ile ilgili olduğunu sanmıyorum, ancak sanal makinelerin neden asıl donanım tarafından zaten göründüğü gibi bir işlevsellik gerçekleştirdiğini düşünüyorum
Ryan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.