Derleyiciler daha hızlı derleme süreleri için çoklu iş parçacığı kullanıyor mu?


16

Derleyicilerimin kursunu doğru hatırlarsam, tipik derleyici aşağıdaki basitleştirilmiş taslağa sahiptir:

  • Sözlüksel analizör kaynak kodu karakter karakter tarar (veya bazı tarama işlevlerini çağırır)
  • Giriş karakterleri dizisi, geçerlilik için sözlüklerin sözlüğüne göre kontrol edilir
  • Sözlük geçerliyse, karşılık geldiği belirteç olarak sınıflandırılır
  • Ayrıştırıcı, belirteç kombinasyonunun sözdizimini doğrular; belirteç .

Teorik olarak kaynak kodunu çeyreklere (veya herhangi bir paydaya) bölmek ve tarama ve ayrıştırma işlemini çok yönlü olarak yapmak mümkün müdür? Çok iş parçacığı kullanan derleyiciler var mı?




1
@RobertHarvey İlk bağlantının en önemli cevabı "ancak derleyicilerin kendileri hala tek iş parçacıklı" yazdı. Yani bu bir hayır mı?
8protons

Yanıtların geri kalanını, özellikle bu cevabı ve gönderdiğim ikinci bağlantıyı okumanızı tavsiye ederim.
Robert Harvey

2
@RobertHarvey Gönderdiğiniz ikinci bağlantı, ne dediğini anladığımdan, derlenmiş uygulamanızın çok iş parçacıklı bir sürümünü üreten bir derleyiciden bahsediyor. Derleyicinin kendisi ile ilgili değil. Paylaşılan kaynaklarınız ve yanıt vermek için zaman ayırdığınız için teşekkür ederiz.
8protons

Yanıtlar:


29

Büyük yazılım projeleri genellikle nispeten bağımsız olarak derlenebilen birçok derleme biriminden oluşur ve bu nedenle derleme genellikle derleyiciyi birkaç kez paralel olarak çağırarak çok kaba bir ayrıntıda paralelleştirilir. Bu işletim sistemi süreçleri düzeyinde gerçekleşir ve derleyici yerine derleme sistemi tarafından koordine edilir. Bunun istediğin şey olmadığını anlıyorum ama çoğu derleyicide paralelleşmeye en yakın şey bu.

Neden? Derleyicilerin yaptığı işlerin çoğu, kolayca paralelleştirmeye borç vermez:

  • Girdiyi birkaç parçaya ayıramaz ve bağımsız olarak lex oluşturamazsınız. Basitlik için lexme sınırlarına bölünmek istersiniz (böylece bir lexme ortasında hiçbir iş parçacığı başlamaz), ancak lexme sınırlarını belirlemek potansiyel olarak çok fazla bağlam gerektirir. Örneğin, dosyanın ortasına atladığınızda, bir dizgi değişmezine atlamadığınızdan emin olmanız gerekir. Ancak bunu kontrol etmek için, daha önce gelen her karaktere bakmak zorundasınız, bu da başlangıçta sadece lexing kadar işe yarıyor. Ayrıca, lexing nadiren modern diller için derleyicilerdeki darboğazdır.
  • Ayrıştırma paralel hale getirmek için daha da zordur. Giriş metnini lexing için bölmenin tüm sorunları, ayrıştırmak için jetonları bölmeye daha fazla uygulanır --- örneğin, bir işlevin nereden başladığını belirlemek temelde başlamak için işlev içeriğini ayrıştırmak kadar zordur. Bu konuda da yollar olsa da, muhtemelen küçük fayda için orantısız olarak karmaşık olacaktır. Ayrıştırma da en büyük darboğaz değildir.
  • Ayrıştırmadan sonra, genellikle ad çözümlemesi yapmanız gerekir, ancak bu, iç içe geçmiş büyük bir ilişki ağına yol açar. Burada bir yöntem çağrısını çözmek için önce bu modüldeki içe aktarma işlemlerini çözmeniz gerekebilir, ancak bunlar başka bir derleme birimindeki adların çözümlenmesini gerektirir , vb.

Bundan sonra biraz daha kolaylaşır. Tip kontrolü ve optimizasyonu ve kod üretimi, prensip olarak, işlev ayrıntı düzeyinde paralelleştirilebilir. Bunu yapan herhangi bir derleyicinin hala çok azını biliyorum, belki de bu kadar büyük bir işi aynı anda yapmak oldukça zordur. Ayrıca, büyük yazılım projelerinin çoğunun "bir sürü derleyiciyi paralel olarak çalıştır" yaklaşımının tüm çekirdeklerinizin (ve bazı durumlarda, hatta tüm sunucu grubunun) meşgul edilmesi için tamamen yeterli olduğu çok fazla derleme birimi içerdiğini göz önünde bulundurmalısınız. Ayrıca, büyük derleme görevlerinde disk G / Ç, gerçek derleme işi kadar darboğaz olabilir.

Bütün bunlar, kod oluşturma ve optimizasyon çalışmalarına paralel bir derleyici biliyorum. Rust derleyici, arka uç çalışmasını (aslında geleneksel olarak "orta uç" olarak kabul edilen kod optimizasyonlarını içeren LLVM) birkaç iş parçacığı arasında bölebilir. Buna "kod-gen birimleri" denir. Yukarıda tartışılan diğer paralelleştirme olasılıklarının aksine, bu ekonomiktir çünkü:

  1. Dilin oldukça büyük derleme birimleri vardır (örneğin, C veya Java ile karşılaştırıldığında), bu nedenle uçuşta çekirdeklerinizden daha az derleme birimi olabilir.
  2. Paralel hale getirilen kısım genellikle derleme süresinin büyük çoğunluğunu alır.
  3. Arka uç çalışması, çoğunlukla utanç verici bir şekilde paraleldir - sadece her bir işlevi bağımsız olarak optimize etmek ve makine koduna çevirmek. Elbette prosedürler arası optimizasyonlar vardır ve kodgen birimleri bunları engeller ve bu nedenle performansı etkiler, ancak herhangi bir anlamsal sorun yoktur.

2

Derleme "utanç verici bir şekilde paralel" bir sorundur.

Kimse bir dosyayı derleme zamanını umursamıyor. İnsanlar 1000 dosya derleme zamanını önemsiyor. Ve 1000 dosya için, işlemcinin her çekirdeği bir kerede bir dosyayı mutlu bir şekilde derleyebilir ve tüm çekirdekleri tamamen meşgul edebilir.

İpucu: "make", doğru komut satırı seçeneğini verirseniz birden çok çekirdek kullanır. Bu olmadan 16 çekirdek sistemde bir dosyayı birbiri ardına derleyecektir. Bu, oluşturma seçeneklerinizdeki tek satırlık bir değişiklikle 16 kat daha hızlı derlenmesini sağlayabileceğiniz anlamına gelir.

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.