Dinamik olarak yazılmış bir dil için derleyici yazarken karşılaşılan zorluklar nelerdir?


9

Gelen bu konuşma , Guido van Rossum o söyleyerek yorumda, Python kodu için bir derleyici yazmak için girişimleri hakkında konuşurken (27:30) 'dir:

tüm güzel dinamik yazma özelliklerini koruyan ve programınızın anlamsal doğruluğunu koruyan bir derleyici yazmak o kadar kolay değil, böylece kapakların altında bir yerde ne tür bir tuhaflık yaparsanız yapın aslında aynı şeyi yapar daha hızlı

Python gibi dinamik olarak yazılmış bir dil için derleyici yazarken yazmanın (olası) zorlukları nelerdir?


Bu durumda dinamik yazma neredeyse en büyük sorun değildir. Python için dinamik bir kapsam.
SK-logic

Diğer insanların platforma dinamik yazım oluşturmanın burada doğru cevap olduğunu savunduğunu belirtmek gerekir. Microsoft , tam da bu nedenle DLR'ye çok para koydu ve NeXT / Apple onlarca yıldır bu bandwagonda yarı yolda. Bu CPython'a yardımcı olmaz, ancak IronPython statik olarak Python'u etkili bir şekilde derleyebileceğinizi kanıtlar ve PyPy zorunda olmamanızı sağlar.
abarnert

2
@ SK-logic Python'da dinamik kapsam belirleme? En son kontrol ettiğimde, dildeki tüm yapılarda sözcüksel kapsam belirleme kullanılır.

1
@ SK-logic Dinamik olarak kod oluşturabilir ve yürütebilirsiniz, ancak bu kod aynı zamanda sözlüksel olarak da çalışır. Bir Python programındaki her bir değişken için, sadece AST'yi inceleyerek bir değişkenin hangi kapsama ait olduğunu kolayca belirleyebilirsiniz. 3.0'dan beri ve bu yüzden benim düşüncemin dışında olan execifadeyi düşünüyor olabilirsiniz (ve muhtemelen Guido'nun konuşması 2012'den beri olduğu gibi). Bir örnek verebilir misiniz? Ve eğer "benimkinden farklı" ise "dinamik kapsam belirleme" tanımınız (en.wikipedia.org/wiki/Dynamic_scoping).

1
@ SK-logic Benim için bir uygulama detayı olan tek şey, locals()çağrılar arasında devam etmenin değerini döndüren değişikliklerdir locals. Belgelenen ve kesinlikle bir uygulama detayı olmayan şey, her bir değişkenin hangi kapsamda arandığını bile değiştiremez localsveya globalsdeğiştiremez. Bir değişkenin her tek kullanımı için, atıfta bulunulan kapsam statik olarak belirlenir. Bu da kesinlikle sözlü olarak kapsamasını sağlar. (Ve btw, evalve execkesinlikle uygulama detayları da değil

Yanıtlar:


16

Guido'nun sorunuzu ifade etme konusundaki ifadesini aşırı basitleştirdiniz. Sorun dinamik olarak yazılan bir dil için derleyici yazmıyor. Sorun, (ölçüt 1) her zaman doğru olan, (ölçüt 2) dinamik yazmayı koruyan ve (ölçüt 3) önemli miktarda kod için belirgin şekilde daha hızlı olan bir yazıyor .

Python'un% 90'ını (başarısız kriterler 1) uygulamak ve sürekli olarak hızlı olmak kolaydır. Benzer şekilde, statik yazarak daha hızlı bir Python varyantı oluşturmak kolaydır (başarısızlık kriteri 2). % 100'ü uygulamak da kolaydır (karmaşık olan bir dili uygulamakla birlikte), ancak şimdiye kadar onu uygulamak için her kolay yol nispeten yavaştır (başarısız kriterler 3).

Doğru bir tercüman artı JIT uygulamak, tüm dili uygular ve bazı kodlar için daha hızlıdır, ancak daha zor olsa da (cf. PyPy) ve sadece JIT derleyicisinin (Psyco onsuz yapmasını otomatikleştirdiyseniz) mümkün olur , ancak hangi kodu hızlandırabileceğiyle çok sınırlıydı). Ancak, statikten bahsederken bunun açıkça kapsam dışı olduğunu unutmayın.(diğer adıyla vaktinden önce) derleyiciler. Sadece yaklaşımının statik derleyiciler için neden çalışmadığını açıklamak için bundan bahsediyorum (veya en azından mevcut karşı örnek yok): Önce programı yorumlamak ve gözlemlemek, daha sonra bir döngü (veya başka bir doğrusal kod için) sonra, yalnızca belirli yineleme için (veya en azından tüm olası yinelemeler için geçerli değildir) geçerli varsayımlara dayanarak cehennemi optimize edin. Beklenti, bu kodun daha sonraki birçok uygulamasının da beklentiyle eşleşmesi ve böylece optimizasyonlardan faydalanmasıdır. Doğruluğu sağlamak için bazı (nispeten ucuz) kontroller eklenir. Tüm bunları yapmak için, ne için uzmanlaşacağınız hakkında bir fikre ve geri dönmek için yavaş ama genel bir uygulamaya ihtiyacınız var. AOT derleyicilerin hiçbiri yoktur. Onlar uzmanlaşmak olamaz hiçgöremedikleri koda göre (örneğin dinamik olarak yüklenen kod) ve dikkatsizce uzmanlaşmak, bir dizi sorunu olan (icache kullanımı, ikili boyut, derleme zamanı, ek dallar) daha fazla kod üretilmesi anlamına gelir.

Tüm dili doğru bir şekilde uygulayan bir AOT derleyicisini uygulamak da nispeten kolaydır: Bu kodla beslendiğinde yorumlayıcının yapacağı şeyi yapmak için çalışma zamanını çağıran kod oluşturun. Nuitka (çoğunlukla) bunu yapar. Bununla birlikte, bu, tercüman olarak gereksiz iş yapmak zorunda kaldığınız için, bayt kodunu derlediğiniz şeyi yapan C kodu bloğuna göndermek için kaydettiğiniz için çok fazla performans avantajı (başarısızlık kriteri 3) sağlamaz. bu sadece oldukça küçük bir maliyettir - mevcut bir tercümanda optimize edilmeye değecek kadar önemli, ancak yeni bir uygulamayı kendi sorunları ile haklı çıkarmak için yeterince önemli değil.

Her üç kriteri de yerine getirmek için ne gerekir? Hiçbir fikrimiz yok. Python programlarından beton türleri, kontrol akışı vb. Hakkında bazı bilgiler elde edebilen bazı statik analiz şemaları vardır. Tek bir temel bloğun kapsamı dışında doğru veri sağlayanlar son derece yavaştır ve tüm programı veya en azından çoğunu görmeleri gerekir. Yine de, yerleşik türlerde birkaç işlemi optimize etmekten başka, bu bilgilerle fazla bir şey yapamazsınız.

Nedenmiş? Açıkça söylemek gerekirse, bir derleyici ya çalışma zamanında yüklenen Python kodunu yürütme yeteneğini kaldırır (başarısızlık ölçütleri 1) ya da herhangi bir Python kodu tarafından geçersiz kılınabilecek varsayımlar yapmaz. Ne yazık ki, programları optimize etmek için hemen hemen her şey yararlıdır içerir: vb tek dize geçirilen çeşitli yollarla kaçırılan edilebilir ithal ribaund olabilir fonksiyonları, sınıflar mutasyona uğramış olabilir veya tamamen değiştirilmesi, modüller keyfi de değiştirilebilir dahil Globals eval, exec, __import__veya çok sayıda başka işlev, bunlardan herhangi birini yapabilir. Aslında bu, neredeyse hiç büyük optimizasyonun uygulanamayacağı anlamına gelir, bu da çok az performans avantajı sağlar (başarısız kriterler 3). Yukarıdaki paragrafa geri dön.


4

En zor sorun, herhangi bir zamanda her şeyin ne tür olduğunu bulmaktır.

C veya Java gibi statik bir dilde, tür bildirimini gördükten sonra, o nesnenin ne olduğunu ve neler yapabileceğini bilirsiniz. Bir değişken bildirilirse int, bir tamsayıdır. Örneğin, çağrılabilir bir işlev başvurusu değildir.

Python'da olabilir. Bu korkunç bir Python, ancak yasal:

i = 2
x = 3 + i

def prn(s):
    print(s)

i = prn
i(x)

Şimdi, bu örnek oldukça aptalca, ama genel fikri gösteriyor.

Daha gerçekçi olarak, yerleşik bir işlevi, biraz farklı bir şey yapan kullanıcı tanımlı bir işlevle değiştirebilirsiniz (aradığınızda argümanlarını kaydeden bir sürüm gibi).

PyPy, kodun gerçekte ne yaptığını izledikten sonra Just-In-Time derlemesini kullanır ve bu da PyPy'nin işleri çok hızlandırmasını sağlar. PyPy bir döngüyü izleyebilir ve döngü her çalıştığında değişkenin fooher zaman bir tam sayı olduğunu doğrulayabilir ; PyPy, döngüdeki fooher geçişte türünü arayan kodu optimize edebilir ve hatta bir tamsayıyı temsil eden Python nesnesinden bile kurtulabilir foove CPU'daki bir kayıtta oturan bir sayı olabilir. PyPy bu şekilde CPython'dan daha hızlı olabilir; CPython, tip aramasını olabildiğince hızlı yapar, ancak aramayı yapmak daha da hızlı değildir.

Ayrıntıları bilmiyorum, ancak Python'u (LLVM kullanarak) hızlandırmak için statik derleyici teknolojisini uygulamaya çalışan Yüksüz Yutmak adlı bir proje olduğunu hatırlıyorum. Google'da Yüksüz Yutmayı aramak ve umduğu gibi neden işe yaramadığına dair bir tartışma bulabileceğinizi görmek isteyebilirsiniz.


Yüksüz Yutmak statik derleme veya statik tiplerle ilgili değildi; Nihai sonuç, CPython yorumlayıcısını, tüm dinamikliği ile LLVM'ye, süslü yeni bir JIT (aslında Parrot veya .NET için DLR veya gerçekten de PyPy gibi) ile taşımaktı. CPython içinde yerel optimizasyonların birçoğunu bulmaktı (bazıları bunu ana hat 3.x'e dönüştürdü). Shedskin muhtemelen Python'u statik olarak derlemek için kullanılan statik tip çıkarımını düşündüğünüz projedir (C ++ 'a rağmen, doğrudan yerel koda değil).
abarnert

Yüksüz Swallow yazarlarından biri olan Reid Kleckner, teknik bağlamlardan çok yönetim ve sponsorluk zorluklarıyla ilgili olmasına rağmen, bu bağlamda okumaya değer olabilecek bir Yüksüz Yut Retrospektifi yayınladı .
abarnert

0

Diğer cevabın dediği gibi, kilit problem tip bilgisini bulmaktır. Bunu statik olarak yapabildiğiniz ölçüde, doğrudan iyi kod oluşturabilirsiniz.

Ancak, statik olarak yapamasanız bile, gerçek tür bilgileri aldığınızda, yalnızca çalışma zamanında makul bir kod üretebilirsiniz . Bu bilgiler genellikle sabittir veya belirli bir kod noktasında belirli bir varlık için en fazla birkaç farklı değere sahiptir. KENDİNİ programlama dili agresif zamanı tür toplama ve çalışma zamanı kod üretimi fikirlerin çoğu öncülük etmiştir. Fikirleri Java ve C # gibi modern JIT tabanlı derleyicilerde yaygın olarak kullanılmaktadır.

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.