Bir mpi_allgather işleminin hesaplama maliyeti bir toplama / dağıtma işlemiyle nasıl karşılaştırılır?


11

Tek bir mpi_allgather işlemi veya bir mpi_scatter ve bir mpi_gather işlemi kullanarak paralelleştirilebilir bir sorun üzerinde çalışıyorum. Bu işlemler bir while döngüsü içinde çağrılır, bu nedenle birçok kez çağrılabilirler.

Bir MPI_allgather şeması ile uygulamada, yinelenen matris çözme için tüm süreçlere dağıtılmış bir vektör topluyorum. Diğer uygulamada, dağıtılmış vektörü tek bir işlemcide (kök düğüm) toplarım, bu işlemcideki doğrusal sistemi çözdüm ve sonra çözelti vektörünü tüm işlemlere dağıtırım.

Tüm operasyonların maliyetinin, dağılım ve toplama operasyonlarının toplamından önemli ölçüde daha yüksek olup olmadığını merak ediyorum. Mesajın uzunluğu karmaşıklığında önemli bir rol oynuyor mu? MPI uygulamaları arasında değişiklik gösterir mi?

Düzenle:


Lütfen iletişimin yapısını ve ilgili boyutları açıklayınız. Bir MPI_Scatterizledi MPI_Gatheraynı iletişim anlamsal sağlamaz MPI_Allgather. Belki de işlemi her iki şekilde ifade ettiğinizde fazlalık söz konusudur?
Jed Brown

Paul, Jed haklı, bunu MPI_Gathertakip etmek mi demek istediniz MPI_Bcast?
Aron Ahmadia

@JedBrown: Biraz daha bilgi ekledim.
Paul

@AronAhmadia: Bir MPI_Bcast kullanmam gerektiğini düşünmüyorum çünkü vektörün bir kısmını tüm işleme değil her bir işleme gönderiyorum. Gerekçem, daha kısa bir mesajın gönderilmesinin genel olarak daha büyük bir mesajdan daha hızlı olacağıdır. Bu mantıklı mı?
Paul

Matris zaten fazla dağılmış mı? Zaten faktörlü mü? Birden çok işlem aynı önbellekleri ve bellek veri yolunu paylaşıyor mu? (Bu, gereksiz sistemlerin çözülme hızını etkiler.) Sistemler ne kadar büyük / pahalı? Neden seri olarak çözmeli?
Jed Brown

Yanıtlar:


9

İlk olarak, kesin cevap şöyledir: (1) kullanım, yani işlev giriş argümanları, (2) MPI uygulama kalitesi ve detayları ve (3) kullandığınız donanım. Genellikle, (2) ve (3), donanım satıcısının ağları için MPI'yi optimize etmesi gibi ilişkilidir.

Genel olarak, MPI kolektiflerinin kaynaştırılması daha küçük mesajlar için daha iyidir, çünkü başlangıç ​​maliyetleri önemsiz olabilir ve aramalar arasında hesaplama süresinde değişiklik varsa kolektifleri engelleyerek yapılan senkronizasyon en aza indirilmelidir. Daha büyük mesajlar için amaç, gönderilen veri miktarını en aza indirmek olmalıdır.

Örneğin, teoride, birincisi genellikle ikincisi açısından uygulansa da, gerçek bir avantaj MPI_Reduce_scatter_blockolmayacak şekilde MPI_Reducetakip edilenden daha iyi olmalıdır MPI_Scatter. Çoğu MPI uygulamasında uygulama kalitesi ve kullanım sıklığı arasında bir korelasyon vardır ve satıcılar, bunun makine sözleşmesi için gerekli olduğu işlevleri açıkça optimize eder.

Öte yandan, bir Mavi Gen MPI_Reduce_scatter_blocküzerindeyse MPI_Allreduce, daha fazla iletişim MPI_Reduceve MPI_Scatterkombine olan kullanımı yapmak aslında biraz daha hızlıdır. Bu yakın zamanda keşfettiğim bir şey ve MPI'daki performans öz-tutarlılığı ilkesinin ilginç bir ihlalidir (bu ilke "Kendinden Tutarlı MPI Performans Kılavuzları" nda daha ayrıntılı olarak açıklanmaktadır ).

Saçılma + toplanmaya karşı belirli bir durumda, birincisinde, tüm verilerin tek bir sürece gidip gelmesi gerektiğini düşünün; , çünkü tüm sıralamaların diğer tüm sıralamalara gönderilecek bazı verileri vardır. Bununla birlikte, tüm düğümlerden bir kerede veri göndermek, bazı ağlar için iyi bir fikir olmayabilir.

Son olarak, bu soruya cevap vermenin en iyi yolu, kodunuzda aşağıdakileri yapmak ve soruyu denemeyle cevaplamaktır.

#ifdef TWO_MPI_CALLS_ARE_BETTER_THAN_ONE
  MPI_Scatter(..)
  MPI_Gather(..)
#else
  MPI_Allgather(..)
#endif

Daha da iyi bir seçenek, kodunuzun ilk iki yineleme sırasında deneysel olarak ölçmesini sağlamak, ardından kalan yinelemeler için hangisinin daha hızlı olduğunu kullanmaktır:

const int use_allgather = 1;
const int use_scatter_then_gather = 2;

int algorithm = 0;
double t0 = 0.0, t1 = 0.0, dt1 = 0.0, dt2 = 0.0;

while (..)
{
    if ( (iteration==0 && algorithm==0) || algorithm==use_scatter_then_gather )
    {
        t0 = MPI_Wtime();
        MPI_Scatter(..);
        MPI_Gather(..);
        t1 = MPI_Wtime();
        dt1 = t1-t0;
    } 
    else if ( (iteration==1 && algorithm==0) || algorithm==use_allgather)
    {
        t0 = MPI_Wtime();
        MPI_Allgather(..);
        t1 = MPI_Wtime();
        dt2 = t1-t0;
    }

    if (iteration==1)
    {
       dt2<dt1 ? algorithm=use_allgather : algorithm=use_scatter_then_gather;
    }
}

Bu kötü bir fikir değil ... ikisine de zaman ayırın ve hangisinin daha hızlı olduğunu belirleyin.
Paul

Çoğu modern HPC ortam donanımı birçok MPI çağrısını optimize eder. Bazen bu inanılmaz hızlanmalara, bazen de son derece opak davranışlara yol açar. Dikkatli ol!
meawoppl

@Jeff: Az önce önemli bir ayrıntıyı bıraktığımı fark ettim ... Teksas Gelişmiş Bilgi İşlem Merkezi'nde, bir yağlı ağaç topoloji ağı kullandıkları bir kümede çalışıyorum. Bu, topla ve topla yayın yaklaşımları arasındaki performans farkını etkiler mi?
Paul

@ Paul Topology burada baskın bir faktör değildir, ancak bir yağlı ağacın önemli ölçüde biseksiyon bant genişliği vardır, bu da her şeyi daha ucuz hale getirmelidir. Ancak, toplanma her zaman herkesten daha ucuz olmalıdır. Yine de daha büyük mesajlar için 2 kattan daha az olabilir.
Jeff

5

Jeff, emin olmanın tek yolu konusunda kesinlikle haklıdır - sonuçta biz bilim insanlarıyız ve bu ampirik bir sorudur - ve bu tür ölçümlerin nasıl uygulanacağı konusunda mükemmel tavsiyeler verir. Şimdi karşıt (veya belki tamamlayıcı) bir görüş sunayım.

Yaygın olarak kullanılacak bir kod yazmak ile onu belirli bir sona ayarlamak arasında bir ayrım yapmak gerekir. Genel olarak, ilk kodumuzu yapıyoruz, böylece a) kodunuzu çok çeşitli platformlarda kullanabiliyoruz ve b) kod önümüzdeki yıllarda korunabilir ve genişletilebilir. Ama bazen diğerini yapıyoruz - bazı büyük makinelerde bir yıllık tahsisatımız var ve bazı gerekli büyük simülasyon setlerine ulaşıyoruz ve ihtiyaç duyduğumuz işi yapmak için belirli bir performans temeline ihtiyacımız var. verilen tahsisin zamanı.

Kod yazarken, onu yaygın olarak kullanılabilir ve bakımı kolay hale getirmek, belirli bir makinede çalışma süresinin yüzde birkaçını tıraş etmekten çok daha önemlidir. Bu durumda, yapılacak doğru şey neredeyse her zaman ne yapmak istediğinizi en iyi açıklayan rutini kullanmaktır - bu genellikle istediğinizi yapan en özel çağrıdır. Örneğin, düz bir allgather veya allgatherv istediğinizi yaparsa, bunu kendi dağılım / gatter işlemlerinden çıkarmak yerine kullanmalısınız. Sebepleri:

  • Kod şimdi ne yapmaya çalıştığınızı daha açık bir şekilde temsil eder, kodun ne yapması gerektiği hakkında hiçbir fikre sahip olmayan ertesi yıl kodunuza gelen bir sonraki kişi için daha anlaşılır hale getirir (bu kişi siz olabilirsiniz);
  • Daha genel bir durumda olmayan bu daha özel durum için MPI düzeyinde optimizasyonlar mevcuttur, böylece MPI kitaplığınız size yardımcı olabilir; ve
  • Kendinizi yuvarlamaya çalışmak büyük ihtimalle geri tepecektir; MPI uygulaması Y.ZZ ile X makinesinde daha iyi performans gösterse bile, başka bir makineye geçtiğinizde veya MPI uygulamanızı yükselttiğinizde çok daha kötü performans gösterebilir.

Bu oldukça yaygın durumda, bazı MPI kolektiflerinin makinenizde makul olmayan bir şekilde yavaş çalıştığını öğrenirseniz, yapılacak en iyi şey mpi satıcısına bir hata raporu vermektir; kendi yazılımınızı MPI kitaplığı düzeyinde düzgün bir şekilde düzeltilmesi gereken uygulama kodunda çalışmaya çalışarak karmaşık hale getirmek istemezsiniz.

Ancak . "Ayarlama" modundaysanız - bir çalışma kodunuz varsa, kısa bir süre içinde çok büyük ölçeklere ulaşmanız gerekir (örn. Bir yıl boyunca tahsis) ve kodunuzu profillendirdiniz ve kodunuzun bu özel bölümünün bir darboğaz olduğunu öğrendiyseniz, bu çok özel ayarları yapmaya başlamak mantıklıdır. Umarım kodunuzun uzun vadeli parçaları olmazlar - ideal olarak bu değişiklikler deponuzun projeye özgü bazı dallarında kalacaktır - ancak bunları yapmanız gerekebilir. Bu durumda, önişlemci yönergeleri veya belirli bir iletişim modeli için "otomatik ayarlama" yaklaşımı ile ayırt edilen iki farklı yaklaşımın kodlanması çok mantıklı olabilir.

Yani Jeff ile aynı fikirde değilim, sadece kod ile başa çıkmak için değiştirmek için böyle göreceli performans soruları ile yeterince endişe ne zaman hakkında bazı bağlam eklemek istiyorum .


Ben bu noktada optimizasyon daha taşınabilirlik ile ilgileniyorum düşünüyorum, ama her zaman aynı derecede taşınabilir ama daha hızlı başka bir uygulama olup olmadığını bilmek merak ediyorum :)
Paul
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.