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ü:
- 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.
- Paralel hale getirilen kısım genellikle derleme süresinin büyük çoğunluğunu alır.
- 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.