Çerçeve

Sorun bildir Kaynağı göster

Bazel'in paralel değerlendirme ve artımlılık modeli.

Veri modeli

Veri modeli aşağıdaki öğelerden oluşur:

  • SkyValue. Düğüm olarak da adlandırılır. SkyValues, derleme boyunca oluşturulan tüm verileri ve derlemenin girişlerini içeren sabit nesnelerdir. Örnekler: giriş dosyaları, çıkış dosyaları, hedefler ve yapılandırılmış hedefler.
  • SkyKey. Bir SkyValue öğesine referans veren kısa ve sabit bir ad (örneğin, FILECONTENTS:/tmp/foo veya PACKAGE://foo).
  • SkyFunction. Anahtarlarına ve bağımlı düğümlerine göre düğüm oluşturur.
  • Düğüm grafiği. Düğümler arasındaki bağımlılık ilişkisini içeren bir veri yapısı.
  • Skyframe. Bazel'ın temel aldığı artımlı değerlendirme çerçevesinin kod adı.

Değerlendirme

Derleme, derleme isteğini temsil eden düğüm değerlendirilerek gerçekleştirilir.

Bazel ilk olarak üst düzey SkyKey anahtarına karşılık gelen SkyFunction değerini bulur. İşlev daha sonra üst düzey düğümü değerlendirmek için ihtiyaç duyduğu düğümlerin değerlendirilmesini ister. Bu da yaprak düğümlerine ulaşılana kadar diğer SkyFunction çağrılarıyla sonuçlanır. Yaprak düğümleri genellikle dosya sistemindeki giriş dosyalarını temsil eder. Son olarak, Bazel üst düzey SkyValue değerini, bazı yan etkileri (dosya sistemindeki çıkış dosyaları gibi) ve derlemede yer alan düğümler arasındaki bağımlılıkların yönlendirilmiş dairesel bir grafiğini elde eder.

SkyFunction, işini yapması gereken tüm düğümleri önceden belirleyemezse birden fazla geçişte SkyKeys isteğinde bulunabilir. Bunun basit bir örneği, sembolik bağlantı olan bir giriş dosyası düğümünü değerlendirmektir. İşlev, dosyayı okumaya çalışır, bunun bir sembolik bağlantı olduğunu anlar ve böylece sembolik bağlantının hedefini temsil eden dosya sistemi düğümünü getirir. Ancak bu kendisi bir sembolik bağlantı olabilir. Bu durumda, orijinal işlevin hedefini de getirmesi gerekir.

İşlevler kodda SkyFunction arayüzü ve ona sağlanan hizmetler ise SkyFunction.Environment adlı bir arayüzle temsil edilir. İşlevlerin yapabileceği şeyler şunlardır:

  • env.getValue yöntemini çağırarak başka bir düğümün değerlendirilmesini isteyin. Düğüm kullanılabilir durumdaysa değeri döndürülür. Aksi takdirde null döndürülür ve işlevin de null döndürmesi beklenir. İkinci durumda bağımlı düğüm değerlendirilir ve ardından orijinal düğüm oluşturucu tekrar çağrılır. Ancak bu kez aynı env.getValue çağrısı, null olmayan bir değer döndürür.
  • env.getValues() yöntemini çağırarak diğer birden fazla düğümün değerlendirilmesini isteyin. Bağımlı düğümler paralel olarak değerlendirilmesi dışında, bu özellik temelde aynıdır.
  • Çağrı sırasında hesaplama yapma
  • Dosya sistemine dosya yazma gibi yan etkileri olabilir. İki farklı işlevin birbirlerinin üzerine basmaktan kaçınmasına dikkat edilmelidir. Genel olarak, yazma yan etkileri (Bazel'den dışarı doğru veri akışı olduğunda) normal kabul edilir. Okuma yan etkileri (kayıtlı bir bağımlılık olmadan Bazel'e doğru veri akışı olduğu) kabul edilmez. Çünkü bunlar kayıtlı olmayan bir bağımlılıktır ve bu nedenle hatalı artımlı derlemelere neden olabilir.

İyi çalışan SkyFunction uygulamaları, bağımlılık istemekten (dosya sistemini doğrudan okumak gibi) başka herhangi bir şekilde verilere erişmekten kaçınır. Bunun nedeni, Bazel'in okunan dosyaya veri bağımlılığını kaydetmemesine ve dolayısıyla hatalı artımlı derlemelere yol açması.

Bir işlev, işini yapmak için yeterli veriye sahip olduğunda, işlevin tamamlandığını belirten null olmayan bir değer döndürmesi gerekir.

Bu değerlendirme stratejisinin bir dizi avantajı vardır:

  • Hermetik. İşlevler yalnızca diğer düğümlere bağlı olarak giriş verileri istiyorsa Bazel, giriş durumu aynıysa aynı verilerin döndürüleceğini garanti edebilir. Tüm gökyüzü işlevleri belirleyiciyse bu, bütünün de belirleyici olacağı anlamına gelir.
  • Doğru ve mükemmel artımlılık. Tüm işlevlerin giriş verilerinin tamamı kaydedilirse, Bazel yalnızca giriş verileri değiştiğinde geçersiz kılınması gereken tam düğüm grubunu geçersiz kılabilir.
  • Paralellik. İşlevler yalnızca bağımlılık isteğinde bulunarak birbirleriyle etkileşim kurabildiğinden, birbirine bağımlı olmayan işlevler paralel olarak çalıştırılabilir ve Bazel, sonucun sıralı çalıştırılmış gibi elde edilecek sonuçlarla aynı olacağını garanti edebilir.

Artımlılık

İşlevler yalnızca diğer düğümlere bağlı olarak giriş verilerine erişebildiğinden, Bazel giriş dosyalarından çıkış dosyalarına kadar eksiksiz bir veri akışı grafiği oluşturabilir ve bu bilgileri yalnızca gerçekten yeniden oluşturulması gereken düğümleri yeniden oluşturmak için kullanabilir: değiştirilen giriş dosyaları kümesinin ters geçişli olarak kapanması.

Özellikle, olası iki artımlılık stratejisi vardır: aşağıdan yukarıya ve yukarıdan aşağıya. Hangisinin ideal olduğu, bağımlılık grafiğinin nasıl göründüğüne bağlıdır.

  • Aşağıdan yukarıya geçersiz kılma işlemi sırasında, bir grafik oluşturulduktan ve değiştirilen girişler kümesi bilindikten sonra, geçişli olarak değiştirilen dosyalara bağlı olan tüm düğümler geçersiz kılınır. Aynı üst düzey düğüm tekrar derlenecekse bu ideal bir seçenektir. Aşağıdan yukarıya geçersiz kılma işleminin, değiştirilip değiştirilmediğini belirlemek için önceki derlemenin tüm giriş dosyalarında stat() çalıştırmasını gerektirdiğini unutmayın. Değişen dosyalar hakkında bilgi edinmek için inotify veya benzer bir mekanizma kullanılarak bu iyileştirme iyileştirilebilir.

  • Yukarıdan aşağıya geçersiz kılma işlemi sırasında, üst düzey düğümün geçişli kapanması kontrol edilir ve yalnızca geçişli kapanışı temiz olan düğümler tutulur. Bu durum, düğüm grafiği büyükse daha iyidir ancak bir sonraki derleme için yalnızca küçük bir alt kümeye ihtiyaç vardır: Aşağıdan yukarıya geçersiz kılma işlemi, ikinci derlemenin küçük grafiğini gösteren yukarıdan aşağıya geçersiz kılma işleminin aksine, ilk derlemenin büyük grafiğini geçersiz kılar.

Bazel yalnızca aşağıdan yukarıya geçersiz kılma işlemi yapar.

Bazel, artımlılığı artırmak için değişiklik ayıklama yöntemini kullanır: Bir düğüm geçersiz kılınırsa ancak yeniden oluşturma işleminden sonra yeni değerinin eski değeriyle aynı olduğu keşfedilirse bu düğümdeki bir değişiklik nedeniyle geçersiz kılınan düğümler "yeniden dikilir".

Örneğin, kullanıcı bir C++ dosyasındaki bir yorumu değiştirirse bundan oluşturulan .o dosyası aynı olur, bu nedenle bağlayıcının tekrar çağrılması gerekmez.

Artımlı Bağlantı / Derleme

Bu modelin ana sınırlaması, bir düğümün geçersiz kılınmasının ya hep ya hiç sorunu olmasıdır: Bir bağımlılık değiştiğinde, bağımlı düğüm her zaman en baştan yeniden oluşturulur. Bu, değişikliklere göre düğümün eski değerini değiştirecek daha iyi bir algoritma olsa bile geçerlidir. Aşağıda, bunun faydalı olacağı durumlara birkaç örnek verilmiştir:

  • Artımlı bağlama
  • Bir JAR dosyasında tek bir sınıf dosyası değiştiğinde, JAR dosyasını tekrar sıfırdan oluşturmak yerine yerinde değiştirmek mümkündür.

Bazel'ın bunları ilkeli bir şekilde desteklememesinin iki sebebi var:

  • Sınırlı performans artışı gerçekleşti.
  • Mutasyonun sonucunun temiz bir yeniden oluşturma sonucuyla aynı olduğunu doğrulamak zordur ve Google, bit bit tekrar tekrarlanabilen derlemelere değer verir.

Şimdiye kadar pahalı bir derleme adımını ayrıştırıp bu şekilde kısmi yeniden değerlendirme gerçekleştirerek yeterince iyi bir performans elde etmek mümkündü. Örneğin, bir Android uygulamasında tüm sınıfları birden çok gruba bölebilir ve ayrı ayrı dex ekleyebilirsiniz. Bu şekilde, bir gruptaki sınıflar değişmezse sıralama işleminin yeniden yapılması gerekmez.

Bazel kavramlarıyla eşleştirme

Burada, Bazel'ın bir derleme gerçekleştirmek için kullandığı anahtar SkyFunction ve SkyValue uygulamalarının üst düzey özeti bulunmaktadır:

  • FileStateValue değeri. lstat() sonucu. İşlev, mevcut dosyalarda yapılan değişiklikleri algılamak için ek bilgileri de hesaplar. Skyframe grafiğindeki en düşük düzeyli düğümdür ve bağımlılığı yoktur.
  • FileValue değeri. Dosyanın gerçek içeriği veya çözümlenmiş yolu ile ilgilenen her şey tarafından kullanılır. Karşılık gelen FileStateValue ve çözülmesi gereken tüm sembolik bağlantılara bağlıdır (örneğin, a/b için FileValue için a çözümlenmiş yolu ve a/b için çözümlenmiş yol gerekir). FileValue ve FileStateValue arasındaki ayrım, dosya içeriğinin gerçekten gerekli olmadığı durumlarda kullanılabilir. Örneğin, dosya sistemi glob'ları (srcs=glob(["*/*.java"]) gibi) değerlendirilirken dosya içerikleri alakasızdır.
  • DirectoryListingStateValue. readdir() sonucu. FileStateValue gibi, bu düğüm de en düşük düzeyli düğümdür ve bağımlılığı yoktur.
  • DirectoryListingValue (Dizin Listeleme Değeri). Dizin girişleriyle ilgilenen her şey tarafından kullanılır. İlgili DirectoryListingStateValue ve dizinle ilişkili FileValue öğesine bağlıdır.
  • PackageValue. Bir BUILD dosyasının ayrıştırılmış sürümünü temsil eder. İlişkili BUILD dosyasının FileValue öğesine ve ayrıca paketteki glob'ları çözümlemek için kullanılan herhangi bir DirectoryListingValue öğesine (bir BUILD dosyasının içeriğini dahili olarak temsil eden veri yapısı) geçişli olarak bağlıdır.
  • ConfiguredTargetValue değerini döndürür. Yapılandırılmış hedefi temsil eder. Bu, bir hedefin analizi sırasında oluşturulan işlem grubunun ve bağımlı yapılandırılmış hedeflere sağlanan bilgilerin bir unsurudur. Karşılık gelen hedefin bulunduğu PackageValue, doğrudan bağımlılıkların ConfiguredTargetValues ve derleme yapılandırmasını temsil eden özel bir düğüme bağlıdır.
  • ArtifactValue. Kaynak veya çıkış yapısı olması fark etmeksizin derlemedeki bir dosyayı temsil eder. Yapılar neredeyse dosyalara eşdeğerdir ve derleme adımlarının gerçek yürütülmesi sırasında dosyalara referans vermek için kullanılır. Kaynak dosyaları, ilişkili düğümün FileValue değerine, çıkış yapıları ise yapıyı oluşturan işlemin ActionExecutionValue değerine bağlıdır.
  • ActionExecutionValue değerini döndürür. Bir eylemin yürütülmesini temsil eder. Giriş dosyalarının ArtifactValues değerine bağlıdır. Yürüttüğü işlem, SkyKeys'in içinde yer alır. Bu, SkyKeys'in küçük olması gerektiği kavramına aykırıdır. Yürütme aşaması çalışmazsa ActionExecutionValue ve ArtifactValue kodlarının kullanılmadığını unutmayın.

Bu şema, görsel bir yardımcı olarak Bazel'ın kendi derlemesinden sonra SkyFunction uygulamaları arasındaki ilişkiyi göstermektedir:

SkyFunction uygulama ilişkilerinin grafiği