Çerçeve

Sorun bildir Kaynağı görüntüle Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

Bazel'in paralel değerlendirme ve artım modeli.

Veri modeli

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

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

Değerlendirme

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

Öncelikle Bazel, üst düzey SkyFunction anahtarına karşılık gelen SkyKey öğesini bulur. Ardından işlev, üst düzey düğümü değerlendirmek için gereken düğümlerin değerlendirilmesini ister. Bu da yaprak düğümlere ulaşılana kadar diğer SkyFunction çağrılarına neden olur. Yaprak düğümler genellikle dosya sistemindeki giriş dosyalarını temsil eder. Son olarak Bazel, üst düzey SkyValue değerini, bazı yan etkileri (ör. dosya sistemindeki çıkış dosyaları) ve derlemeye dahil olan düğümler arasındaki bağımlılıkların yönlendirilmiş döngüsüz grafiğini elde eder.

Bir SkyFunction, görevini yerine getirmek için hangi düğümlere ihtiyacı olduğunu önceden bilemiyorsa birden fazla geçişte SkyKeys isteyebilir. Basit bir örnek, sembolik bağlantı olduğu anlaşılan bir giriş dosyası düğümünü değerlendirmektir: İşlev, dosyayı okumaya çalışır, bunun bir sembolik bağlantı olduğunu fark eder ve böylece sembolik bağlantının hedefini temsil eden dosya sistemi düğümünü getirir. Ancak bu da sembolik bağlantı olabilir. Bu durumda orijinal işlevin de hedefini getirmesi gerekir.

İşlevler, kodda SkyFunction arayüzü ve SkyFunction.Environment adlı bir arayüz tarafından sağlanan hizmetlerle temsil edilir. İşlevlerin yapabileceği işlemler:

  • env.getValue numaralı telefonu arayarak başka bir düğümün değerlendirilmesini isteyin. Düğüm varsa değeri döndürülür, aksi takdirde null döndürülür ve işlevin kendisinin 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() işlevini çağırarak birden fazla başka düğümün değerlendirilmesini isteyin. Bu işlev, bağımlı düğümler paralel olarak değerlendirildiği için temelde aynı işlemi yapar.
  • Çağrıldıkları sırada hesaplama yapma
  • Dosya sistemine dosya yazma gibi yan etkileri olabilir. İki farklı işlevin birbirinin alanına girmemesi için dikkatli olunmalıdır. Genel olarak, yazma yan etkileri (verilerin Bazel'den dışarı aktığı yerler) sorunsuz çalışır. Okuma yan etkileri (verilerin kayıtlı bir bağımlılık olmadan Bazel'e aktığı yerler) ise kayıtlı olmayan bir bağımlılık oldukları ve bu nedenle yanlış artımlı derlemelere neden olabilecekleri için sorunsuz çalışmaz.

İyi tasarlanmış SkyFunction uygulamaları, bağımlılıkları istemek dışında (ör. dosya sistemini doğrudan okuyarak) verilere başka bir şekilde erişmekten kaçınır. Aksi takdirde Bazel, okunan dosyadaki veri bağımlılığını kaydetmez ve bu da yanlış artımlı derlemelere yol açar.

Bir işlev, görevini yerine getirmek için yeterli veriye sahip olduğunda tamamlanmayı belirten bir null olmayan değer döndürmelidir.

Bu değerlendirme stratejisinin çeşitli avantajları vardır:

  • Sızdırmazlık. İşlevler yalnızca diğer düğümlere bağlı olarak giriş verilerini isterse Bazel, giriş durumu aynı olduğunda aynı verilerin döndürüleceğini garanti edebilir. Tüm gökyüzü işlevleri deterministikse bu, tüm derlemenin de deterministik olacağı anlamına gelir.
  • Artımlılığı düzeltin ve mükemmelleştirin. Tüm işlevlerin tüm giriş verileri kaydedilirse Bazel, giriş verileri değiştiğinde yalnızca geçersiz kılınması gereken tam düğüm kümesini geçersiz kılabilir.
  • Paralellik. İşlevler yalnızca bağımlılık isteğinde bulunarak birbirleriyle etkileşime girebildiğinden, birbirine bağlı olmayan işlevler paralel olarak çalıştırılabilir ve Bazel, sonuçların sıralı olarak çalıştırılmış gibi 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 kapanımı.

Özellikle iki olası artış stratejisi vardır: alttan yukarıya ve yukarıdan aşağıya. Hangisinin en iyi 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 sırasında, bir grafik oluşturulduktan ve değiştirilen girişler kümesi bilindikten sonra, değiştirilen dosyalara geçişli olarak bağlı olan tüm düğümler geçersiz kılınır. Aynı üst düzey düğüm tekrar oluşturulacaksa bu yöntem idealdir. Alttan yukarıya geçersiz kılma işleminin, değiştirilip değiştirilmediklerini belirlemek için önceki derlemenin tüm giriş dosyalarında stat() komutunun çalıştırılmasını gerektirdiğini unutmayın. Bu durum, değişen dosyalar hakkında bilgi edinmek için inotify veya benzer bir mekanizma kullanılarak iyileştirilebilir.

  • Yukarıdan aşağıya geçersiz kılma sırasında, üst düzey düğümün geçişli kapanımı kontrol edilir ve yalnızca geçişli kapanımı temiz olan düğümler tutulur. Bu, düğüm grafiği büyükse ancak sonraki derleme için yalnızca küçük bir alt kümesi gerekiyorsa daha iyidir: Alttan yukarıya geçersiz kılma, yalnızca ikinci derlemenin küçük grafiğinde ilerleyen üstten aşağıya geçersiz kılmanın aksine, ilk derlemenin daha 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, daha fazla artış elde etmek için değişiklik budama özelliğini kullanır: Bir düğüm geçersiz kılınır ancak yeniden oluşturma sırasında yeni değerinin eski değeriyle aynı olduğu anlaşılırsa bu düğümdeki değişiklik nedeniyle geçersiz kılınan düğümler "yeniden oluşturulur".

Örneğin, bir C++ dosyasındaki yorum değiştirilirse bu dosya kullanılarak oluşturulan .o dosyası aynı olur. Bu nedenle, bağlayıcıyı tekrar çağırmak gereksizdir.

Artımlı Bağlama / Derleme

Bu modelin temel sınırlaması, bir düğümün geçersiz kılınmasının her şeyi kapsayan bir işlem olmasıdır: Bir bağımlılık değiştiğinde, daha iyi bir algoritma olsa bile bağımlı düğüm her zaman sıfırdan yeniden oluşturulur. Bu algoritma, düğümün eski değerini değişikliklere göre değiştirebilir. Bu özelliğin yararlı olacağı birkaç örnek:

  • Artımlı bağlama
  • Bir JAR dosyasında tek bir sınıf dosyası değiştiğinde, JAR dosyasını baştan oluşturmak yerine yerinde değiştirebilirsiniz.

Bazel'in bunları prensipli bir şekilde desteklememesinin iki nedeni vardır:

  • Performansta sınırlı artışlar oldu.
  • Mutasyon sonucunun temiz bir yeniden derleme sonucuyla aynı olduğunu doğrulamanın zor olması ve Google'ın bit bit tekrarlanabilir derlemelere değer vermesi.

Şimdiye kadar, pahalı bir derleme adımını parçalayarak ve bu şekilde kısmi yeniden değerlendirme yaparak yeterince iyi bir performans elde etmek mümkündü. Örneğin, bir Android uygulamasında tüm sınıfları birden fazla gruba ayırabilir ve bunları ayrı ayrı dex'leyebilirsiniz. Bu sayede, bir gruptaki sınıflar değişmediyse dexing işleminin yeniden yapılması gerekmez.

Bazel kavramlarıyla eşleme

Aşağıda, Bazel'in derleme gerçekleştirmek için kullandığı temel SkyFunction ve SkyValue uygulamalarının üst düzey bir özeti verilmiştir:

  • FileStateValue. lstat() sonucunda elde edilen değer. Mevcut dosyalar için bu işlev, dosyada yapılan değişiklikleri tespit etmek amacıyla ek bilgiler de hesaplar. Bu, Skyframe grafiğindeki en düşük seviyeli düğümdür ve bağımlılığı yoktur.
  • FileValue. Bir dosyanın gerçek içeriği veya çözümlenmiş yoluyla ilgilenen her şey tarafından kullanılır. İlgili FileStateValue ve çözülmesi gereken tüm sembolik bağlantılara (ör. a/b için FileValue, a'ün çözülmüş yolunu ve a/b'nin çözülmüş yolunu gerektirir) bağlıdır. FileValue ile FileStateValue arasındaki fark önemlidir. Çünkü ikincisi, dosyanın içeriğinin aslında gerekli olmadığı durumlarda kullanılabilir. Örneğin, dosya sistemi globları (srcs=glob(["*/*.java"]) gibi) değerlendirilirken dosya içerikleri alakasızdır.
  • DirectoryListingStateValue. readdir() işleminin sonucu. FileStateValue gibi bu da en düşük düzeyli düğümdür ve bağımlı öğesi yoktur.
  • DirectoryListingValue. Bir dizinin girişleriyle ilgilenen her şey tarafından kullanılır. İlgili DirectoryListingStateValue ve dizinin ilişkili FileValue öğesine bağlıdır.
  • PackageValue. BUILD dosyasının ayrıştırılmış sürümünü temsil eder. İlişkili BUILD dosyasının FileValue değerine ve ayrıca paketteki glob'ları çözmek için kullanılan tüm DirectoryListingValue değerlerine (BUILD dosyasının içeriğini dahili olarak temsil eden veri yapısı) bağlıdır.
  • ConfiguredTargetValue. Yapılandırılmış bir hedefi temsil eder. Bu, bir hedef analiz edilirken oluşturulan işlemler kümesinin ve bağımlı yapılandırılmış hedeflere sağlanan bilgilerin bir demetidir. PackageValue karşılık gelen hedef, 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. Derlemedeki bir dosyayı (kaynak veya çıkış yapısı) temsil eder. Yapılar, dosyalarla neredeyse eşdeğerdir ve derleme adımlarının gerçek yürütülmesi sırasında dosyalara başvurmak 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. Bir işlemin yürütülmesini temsil eder. Giriş dosyalarının ArtifactValues bağlıdır. Yürüttüğü işlem, SkyKey'inde yer alır. Bu durum, SkyKey'lerin küçük olması gerektiği kavramına aykırıdır. Yürütme aşaması çalışmıyorsa ActionExecutionValue ve ArtifactValue parametrelerinin kullanılmadığını unutmayın.

Bu şema, görsel bir yardımcı olarak Bazel'in kendisinin derlenmesinden sonra SkyFunction uygulamaları arasındaki ilişkileri gösterir:

SkyFunction uygulama ilişkilerinin grafiği