Çerçeve

Sorun bildirme Kaynağı görüntüleme Nightly · 8.0 . 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel'in paralel değerlendirme ve artımlı model.

Veri modeli

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

  • SkyValue. Düğüm 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: SkyValue'a referans vermek için kullanılan kısa ve değiştirilemeyen bir ad (ör. FILECONTENTS:/tmp/foo veya PACKAGE://foo).
  • SkyFunction. Anahtarlarına ve bağımlı düğümlerine göre düğümler oluşturur.
  • Düğüm grafiği. Nodlar arasındaki bağımlılık ilişkisini içeren bir veri yapısı.
  • Skyframe. Bazel'in temel aldığı artımlı değerlendirme çerçevesinin kod adı.

Değerlendirme

Derleme, derleme isteğini temsil eden düğüm değerlendirilerek yapılır.

Öncelikle Bazel, üst düzey SkyKey anahtarına karşılık gelen SkyFunction öğesini bulur. Ardından işlev, üst düzey düğümü değerlendirmek için ihtiyaç duyduğu 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 ihtiyaç duyduğu tüm düğümleri önceden söyleyemiyorsa SkyKeys'yi birden fazla geçişte isteyebilir. Basit bir örnek, sembolik bağlantı olduğu ortaya çıkan bir giriş dosyası düğümünü değerlendirmektir: İşlev dosyayı okumaya çalışır, 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 da bir sembolik bağlantı olabilir. Bu durumda, orijinal işlevin kendi hedefini de getirmesi gerekir.

İşlevler kodda SkyFunction arayüzü ve kendisine sağlanan hizmetler SkyFunction.Environment adlı bir arayüz tarafından temsil edilir. İşlevler şunları yapabilir:

  • env.getValue çağrısı yaparak 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 null döndürmesi beklenir. İkinci durumda, bağımlı düğüm değerlendirilir ve ardından orijinal düğüm oluşturucu yeniden çağrılır ancak bu kez aynı env.getValue çağrısı null olmayan bir değer döndürür.
  • env.getValues() çağrısı yaparak birden fazla düğümün değerlendirilmesini isteyin. Bu yöntem, bağımlı düğümlerin paralel olarak değerlendirilmesi dışında temel olarak aynı işlemi gerçekleştirir.
  • Çağrılmaları sırasında hesaplama yapma
  • Dosya sistemine dosya yazma gibi yan etkileri olabilir. İki farklı işlevin birbirinin alanına girmediğinden emin olun. Genel olarak yazma yan etkileri (verilerin Bazel'den dışarıya aktığı durumlar) kabul edilir. Okuma yan etkileri (verilerin kayıtlı bir bağımlılık olmadan Bazel'e içeriye aktığı durumlar) ise kayıtlı bir bağımlılık olmadığı ve bu nedenle yanlış artımlı derlemelere neden olabileceği için kabul edilmez.

İyi çalışan SkyFunction uygulamaları, verilere bağımlılıkları istemekten başka bir şekilde (ör. dosya sistemini doğrudan okuyarak) erişmekten kaçınır. Bunun nedeni, Bazel'in, okunan dosyaya veri bağımlılığını kaydettirmemesi ve böylece yanlış artımlı derlemelere neden olmasıdır.

Bir işlev, görevini yapacak kadar veriye sahip olduğunda, tamamlanmayı belirten null olmayan bir değer döndürmelidir.

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

  • Hermetiklik. İş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 sky işlevleri deterministikse derlemenin tamamı da deterministik olur.
  • Doğru ve mükemmel artımlılık. Tüm işlevlerin tüm giriş verileri kaydedilirse Bazel, giriş verileri değiştiğinde yalnızca geçersiz kılınması gereken düğüm grubunu geçersiz kılar.
  • Paralellik. İşlevler yalnızca bağımlılık isteğinde bulunarak birbirleriyle etkileşime geçebildiğinden, birbirine bağlı olmayan işlevler paralel olarak çalıştırılabilir ve Bazel, sonucun sırayla çalıştırılmış işlevlerle 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ş dosyası grubunun ters geçişli kapatması.

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

  • Aşağıdan yukarıya doğru geçersiz kılma işlemi sırasında, bir grafik oluşturulduktan ve değiştirilen girişler belirlendikten 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ün tekrar oluşturulması gerekiyorsa bu yöntem en uygun yöntemdir. Aşağıdan yukarı doğru geçersiz kılma işleminde, önceki derlemenin tüm giriş dosyalarında stat()'ün çalıştırılarak değiştirilip değiştirilmediğinin belirlenmesi gerektiğini unutmayın. Değişen dosyalar hakkında bilgi edinmek için inotify veya benzer bir mekanizma kullanılarak bu durum iyileştirilebilir.

  • Yukarıdan aşağı doğru geçersiz kılma işlemi sırasında, üst düzey düğümün geçişli kapatması kontrol edilir ve yalnızca geçişli kapatması temiz olan düğümler tutulur. Bu yöntem, düğüm grafiği büyükse ancak sonraki derlemenin yalnızca küçük bir alt kümesine ihtiyacı varsa daha iyidir: Aşağıdan yukarı doğru geçersiz kılma, yalnızca ikinci derlemenin küçük grafiğini gezen yukarıdan aşağı doğru geçersiz kılma işleminin aksine, ilk derlemenin daha büyük grafiğini geçersiz kılar.

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

Daha fazla artımlılık elde etmek için Bazel değişiklik budama özelliğini kullanır: Bir düğüm geçersiz kılınırsa ancak yeniden oluşturulduktan sonra yeni değerinin eski değeriyle aynı olduğu anlaşılırsa bu düğümdeki bir değişiklik nedeniyle geçersiz kılınan düğümler "yeniden canlandırılır".

Örneğin, bir C++ dosyasında bir yorum değiştirilirse bu özellik faydalıdır: Bu durumda, bu dosyadan oluşturulan .o dosyası aynı olur ve bu nedenle bağlayıcıyı tekrar çağırmanız gerekmez.

Artımlı Bağlama / Derleme

Bu modelin ana sınırlaması, bir düğümün geçersiz kılınmasının "ya hep ya hiç" şeklinde olmasıdır: Bir bağımlılık değiştiğinde, düğümün eski değerini değişikliklere göre değiştirecek daha iyi bir algoritma olsa bile bağımlı düğüm her zaman sıfırdan yeniden oluşturulur. Bunun yararlı olacağı birkaç örnek:

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

Bazel'in bu tür işlemleri temel bir şekilde desteklememesinin iki nedeni vardır:

  • Performans açısından sınırlı kazanımlar elde edildi.
  • Mutasyonun sonucunun, temiz bir yeniden oluşturma işleminin sonucuyla aynı olduğunu doğrulama zorluğu ve Google, bit için bit tekrarlanabilir yapıları önemser.

Şimdiye kadar, pahalı bir derleme adımını parçalara ayırarak ve bu şekilde kısmi yeniden değerlendirme yaparak yeterince iyi 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'e dönüştürebilirsiniz. Bu sayede, bir gruptaki sınıflar değişmediyse sınıfları kaldırma işleminin yeniden yapılması gerekmez.

Bazel kavramlarıyla eşleme

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

  • FileStateValue. Bir lstat() sonucu. Mevcut dosyalar için işlev, dosyadaki değişiklikleri algılamak amacıyla ek bilgiler de hesaplar. Bu, Skyframe grafiğindeki en düşük düzeyli 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'e ve çözülmesi gereken tüm sembolik bağlantılara bağlıdır (ör. a/b için FileValue, a'ın ve a/b'nin çözüldüğü yolu gerektirir). FileValue ile FileStateValue arasındaki fark önemlidir çünkü FileStateValue, dosyanın içeriğine gerçekten ihtiyaç duyulmayan durumlarda kullanılabilir. Örneğin, dosya sistemi glob'ları (srcs=glob(["*/*.java"]) gibi) değerlendirilirken dosya içerikleri alakasızdır.
  • DirectoryListingStateValue. readdir() işlevinin sonucu. FileStateValue gibi bu da en düşük düzeydeki düğümdür ve bağımlılığı yoktur.
  • DirectoryListingValue. Bir dizinin girişleriyle ilgilenen her şey tarafından kullanılır. İlgili DirectoryListingStateValue'ye ve dizinin ilişkili FileValue'sine 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 değerine ve ayrıca paketteki glob'leri (BUILD dosyasının içeriğini dahili olarak temsil eden veri yapısı) çözmek için kullanılan tüm DirectoryListingValue değerlerine bağlıdır.
  • ConfiguredTargetValue. Yapılandırılmış bir hedefi temsil eder. Bu hedef, bir hedefin analizi sırasında oluşturulan işlem grubunun ve bağımlı yapılandırılmış hedeflere sağlanan bilgilerin bir tuple'sidir. İlgili 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. Derlemedeki bir dosyayı (kaynak veya çıkış yapı) temsil eder. Yapılar, dosyalara neredeyse eşdeğerdir ve derleme adımlarının gerçekte 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. Bir işlemin yürütülmesini temsil eder. Giriş dosyalarının ArtifactValues değerine bağlıdır. Yaptığı işlem SkyKey'ında yer alıyor. Bu durum, SkyKey'ların küçük olması gerektiğine dair konsepte aykırıdır. Yürütme aşaması çalıştırılmazsa ActionExecutionValue ve ArtifactValue değerlerinin kullanılmadığını unutmayın.

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

SkyFunction uygulama ilişkilerinin grafiği