Paralel Bilimsel Hesaplama Yazılım Geliştirme Dili?


18

Sıfırdan paralel bir bilimsel hesaplama yazılımı geliştirmek istiyorum. Hangi dilin başlayacağı konusunda bazı düşünceler istiyorum. Program, txt dosyalarına veri okuma / yazma ve paralel olarak yoğun hesaplamaların yapılmasını, birçok LU faktorizasyonunu ve seyrek lineer çözücülerin kullanımını içerir. Düşündüğüm aday çözümler OpenMP veya co-array ile Fortran 2003/2008, openmp cilk + veya TBB, python ile C ++. Diğer, belgelenmiş, önerilerinizi bekliyoruz! Çok iyi biliyorum C, Fortran ve Java (bu sırayla). Python'da bazı temel senaryolar yaptım ama temel şeyler.

Fortran'ın çok hızlı olduğunu biliyorum, ancak bakımı ve paralelleştirilmesi zor. Dış kütüphaneler vb Python gibi sürece C ++ yavaş olduğu söylenir, ama tam ölçekli, endüstriyel düzeyde yazılım üzerine yazmak gerçekçi mi?

Yazılım büyük miktarda veriyi işleyebilmeli ve bilimsel hesaplamalarda etkili olmalıdır. Performans esastır.

Arka plan için, zaten Fortran'da yazılmış çalışan bir yazılımım var. Birçok insan uzun yıllar boyunca gelişime dahil oldu ve kod gerçekten kirli. Kodun sürdürülmesi ve paralel hale getirilmesi bir kabus oldu ve ben alternatifleri düşünüyorum.

Petros


5
Bir C ++ wonk olarak, Fortran'ı korumak için zor demezdim. Sürdürülebilirlik, çoğunlukla dil seçimine değil, iyi uygulamalara bağlıdır. C ++ 'ın yavaşlığı aşırı satılmıştır. Ayrıca, veri boyutunuzu ve geri dönüş süresi gereksinimlerinizi tanımlamak için bu yayını artırmanızı tavsiye ederim. Kiminle konuştuğuma bağlı olarak 9 ya da 10 büyüklükte "büyük" değişkenlik gördüm.
Bill Barth

@BillBarth Mevcut Fortran koduyla ilgili sorun, üç kişinin farklı uygulamalar kullanmasıydı. C arka planından geliyorum, F77 kökenli bir adam ve Matlab'dan başka bir adam. Veriler ayrılamaz ve en büyük boyut sistemi için boyutlandırılmamıştır (son zamanlarda dahil oldum). Kod, 350 saniyede 240'lık bir zaman ufku (geçen zaman) üzerinde 72000 diferansiyel ve 74000 cebirsel denklem ile sistemi simüle edebildi. Paralel hale getirmek için OpenMP kullanarak bunu 170'lere indirdim. Şimdi birkaç durumu paralel olarak çalıştırmam gerekiyor (güvenlik kontrolünü taramak için).
electrique

4
@BillBarth, C ++ becerilerini satmak için çok mütevazı, ancak "C ++ yavaşlığının fazla satıldığı" ifadesinde de çok cömert. Scicomp.stackexchange.com'da bu soruyu tartışan bir dizi C ++ vs Fortran iş parçacığı vardır ve genel sonuç, C ++ 'dan hemen hemen tüm durumlar için Fortran'dan daha yavaş olduğu doğru değildir. Şahsen bugün kentsel bir mit olarak düşünülebileceğini düşünüyorum. Ne olduğunu çok gerçek kod hesap maintainability içine almak, o zaman Fortran Bugün çok iyi başarılı olmamasıdır.
Wolfgang Bangerth

2
@BillBarth ve diğerleri, Fortran, C ++ ve diğer dillerin genel özelliklerini tartışmaya devam etmek istiyorsanız, lütfen bunu scicomp sohbet odasına ve @ özel olarak ele almak istediğiniz herkese götürün .
Aron Ahmadia

1
@AronAhmadia: ah, hadi, Jed'e söyleyecek çok şeyim var ;-) (Jed: başka bir zaman. Bizim durumumuzda, seyrek matrisler için STL yok, ancak adaptif örgü veri yapılarında çok fazla.)
Wolfgang Bangerth

Yanıtlar:


19

İzin verin ve gereksinimlerinizi yıkın:

  • İdame
  • Metin verilerini okuma / yazma
  • LU çarpanlara ayırma için güçlü arayüzler / kapasite
  • Seyrek doğrusal çözücüler
  • Büyük verilere performans ve ölçeklenebilirlik

Bu listeden aşağıdaki dilleri dikkate alırım:

C, C ++, Fortran, Python, MATLAB, Java

Julia gelecek vaat eden yeni bir dildir, ancak topluluk hala etrafında şekillenmektedir ve herhangi bir büyük yeni kodda konuşlandırılmamıştır.

Metin verilerini okuma / yazma

Bu, herhangi bir programlama dilinde kolayca elde edilebilir. G / Ç erişiminizi uygun şekilde arabelleğe aldığınızdan ve birleştirdiğinizden emin olun ve dikkate almanız gereken dillerden iyi bir performans elde edersiniz. Performansları nasıl kullanacağınızı bilmiyorsanız C ++ 'ta akış nesnelerinden kaçının.

LU çarpanlara ayırma için güçlü arayüzler / kapasite

Yoğun LU çarpanlarına ayırma işlemi yapıyorsanız, paralel işlevsellik için LAPACK veya ScaLAPACK / Elemental kullanmak istersiniz. LAPACK ve ScaLAPACK Fortran, Elemental C ++ ile yazılmıştır. Her üç kütüphane de performans sergiliyor ve iyi destekleniyor ve belgeleniyor. Bunlara, düşünmeniz gereken dillerden herhangi biriyle arayüz oluşturabilirsiniz.

Seyrek doğrusal çözücüler

Önceden serbestçe temin edilebilen seyrek doğrusal çözücülerin neredeyse tamamı , iyi belgelenmiş ve desteklenen C ile yazılmış PETSc aracılığıyla elde edilebilir . Dikkate almanız gereken herhangi bir dilden PETSc ile arayüz oluşturabilirsiniz.

Büyük verilere performans ve ölçeklenebilirlik

Bahsettiğiniz tek paralel programlama paradigmaları, paylaşılan bellek tabanlı, yani MPI tabanlı (mesaj geçiren), dağıtılmış bellek hesaplama yaklaşımını düşünmediğiniz anlamına gelir. Deneyimlerime göre, dağıtılmış bellek çözümü kullanarak bir düzine çekirdeğin ötesine ölçeklenen kod yazmak çok daha kolay. Hemen hemen tüm Üniversite "kümeleri" MPI tabanlıdır, büyük paylaşılan bellek makineleri pahalıdır ve buna bağlı olarak nadirdir. MPI'yı yaklaşımınız için düşünmelisiniz, ancak tavsiyem seçtiğiniz programlama paradigmasından bağımsız olarak geçerli olacaktır.

Düğüm üzerinde performans ile ilgili olarak, kendiniz sayısal rutinler yazıyorsanız, Fortran'da iyi seri performans elde etmek en kolay yoldur. C, C ++ veya Python'da biraz deneyiminiz varsa, çok benzer bir performans elde edebilirsiniz (C ve C ++, Fortran, Python ve MATLAB ile fazla çaba harcamadan yaklaşık% 25 zaman yükü ile gelir). MATLAB bunu bir JIT derleyicisi ve çok iyi doğrusal cebir ifadesi ile yapar. Python'dan talep edilen performansı elde etmek için muhtemelen Cython, numpy, numexpr veya gömülü sayısal çekirdekler kullanmanız gerekecektir. Java'nın performansı hakkında yorum yapamam, çünkü dili çok iyi bilmiyorum, ancak bir uzman tarafından yazılırsa bunun Python'dan uzak olmadığından şüpheleniyorum.

Arayüzler hakkında bir not

Umarım, düşündüğünüz programlama dillerinden herhangi birinde istediğiniz her şeyi yapabileceğinize ikna oldum. Java kullanıyorsanız, C arayüzleri biraz zorlayıcı olacaktır. Python, ctypes, Cython ve f2py aracılığıyla mükemmel C ve Fortran arayüz desteğine sahiptir. LAPACK zaten sarılmış ve scipy ile kullanılabilir. MATLAB, yerel kütüphanelerinde ihtiyaç duyduğunuz tüm işlevlere sahiptir, ancak kolayca ölçeklenebilir veya kümelerde çalıştırılması özellikle kolay değildir. Java, JNI ile C ve Fortran arabirimlerini destekleyebilir , ancak kümelerde ve bilimsel hesaplama için paralel yazılımlarda yaygın olarak bulunmaz.

İdame

Bunun birçoğu kişisel lezzete inecek, ancak sürdürülebilirlik konusundaki genel fikir birliği, yazılımınızdaki kod satır sayısını en aza indirmek, iyi tanımlanmış arabirimlerle modüler kod yazmak ve hesaplama yazılımı sağlamaktır. uygulamanın doğruluğunu ve işlevselliğini doğrulayan testler.

Öneri

Ben şahsen Python ile şans çok oldu ve birçok hesaplama projeler için tavsiye. Bence bunu projeniz için kuvvetle düşünmelisiniz. Python ve MATLAB muhtemelen bilimsel hesaplama için mevcut olan dillerden en ifadelidir. Python'u başka herhangi bir programlama diliyle kolayca arabirimleyebilirsiniz, mevcut Fortran uygulamanızı sarmak için P2hon'u kullanabilir ve işlevselliği koruduğunuzu doğrularken Python'da hangi parçaları istediğinizi yeniden parçalayabilirsiniz. Şu anda, resmi Python 2.7 uygulamasının scipy ile bir kombinasyonunu tavsiye ederim . Bu yığınla kolayca kullanılabilen Enthought Python Distribution'dan başlayabilirsiniz .

Bunların çoğunu C, C ++ veya Fortran'da da yapabilirsiniz. C ve C ++, çok fazla deneyime sahip profesyonel geliştiriciler için çok çekici dillerdir, ancak sıklıkla yeni geliştiricilere seyahat eder ve bu anlamda muhtemelen daha akademik bir kod için harika bir fikir değildir. Fortran ve MATLAB akademik hesaplamada popülerdir, ancak Python'un sunduğu gelişmiş veri yapıları ve ifade gücü bakımından zayıftır (örneğin bir Python dict nesnesini düşünün).

İlgili sorular:


1
Çok iyi belgelenmiş, her şey dahil bir cevap. Fortran altında çok fazla Lapack kullanıyorum. Python'a bir göz atacağım ve başlamak için Fortran kodumu sarmaya çalışacağım ve yavaş yavaş Python'a geçeceğim. Beni korkutan tek şey, sahip olabileceğim% 25 zaman yükü. Ama daha etkileyici kod ve daha iyi paralel bilgi işlem işleminin faydası ile birlikte gelirse, bunun için gideceğim. Paylaşılan bellekten bahsetmiştim, çünkü yazılım şu anda Windows ve Linux altında Uni'deki araştırmacıların 2,4,8,24,48 çekirdekli paylaşılan bellek bilgisayarlarında etkileşimli bir şekilde çalıştığı (veriler üzerinde bir değişiklik yapın ve yeniden çalıştırın).
electrique

3
Python'da yazılan sayısal çekirdekler için% 25 ek yükü nasıl talep edebileceğinizi bilmiyorum. Saf Python sayısal çekirdekleri genellikle C'den 100 kat daha yavaştır. Numpy ve numexpr belirli ifadelerle iyi bir iş yapabilir, ancak bu Python'da neredeyse yeni sayısal çekirdekler yazmaz. Cython bazı şeyleri hızlı yapabilir, ancak genellikle C'nin% 25'inde değildir. Python iyi bir "tutkal" dildir, ancak Aron'un bunu performansa duyarlı görevler için genel amaçlı bir çözüm olarak üstlendiğini düşünüyorum.
Jed Brown

G / Ç, Fortran'ın zayıf noktasıdır, çünkü Fortran, G / Ç'de çok fazla yapı gerektirir. Laboratuvarımdaki Cython ile çalışan meslektaşları ile konuşmamın ikinci el deneyimim Jed'in Cython hakkında söylediklerine uyuyor; Bunlardan en az biri performans yoğun görevler için Cython'un yerini almak üzere elle ayarlanmış C yazar ve sonra ortaya çıkan C kodunu çağıran Python'un performansının Aron'un iddiasına daha yakın olduğuna inanıyorum. Ayrıca, PETSc ve Python'dan bahsedecekseniz, petsc4py'den de bahsedebilirsiniz. Son gördüğüm (birkaç yıl önceydi), Java için iyi bir MPI arabirimi yoktu. Bu değişti mi?
Geoff Oxberry

@ GeoffOxberry: Java MPI bağlamaları var, ancak yaklaşık on yıl içinde güncellenmemiş. Durumlarını şüpheli görüyorum. Fortran'ın çok hızlı gitmek için yapılabilecek çok sayıda I / O seçeneği vardır. Paralel HDF5'i (ve genellikle HDF5'i) keşfetmenizi öneririm. G / Ç gerçekten baskınsa (çalışma süresinin% 50'sinden fazlası), daha ciddi önlemler alınabilir, ancak aksi takdirde, HDF benzeri arayüzün kalitesi ve taşınabilirliği muhtemelen buna değer.
Bill Barth

@BillBarth: Bunu kontrol etmem gerekecek. Fortran I / O hakkındaki yorumum, bir keresinde Fortran'a bir girdi dosyası ayrıştırıcısı yazmamı öneren birinin bakış açısından geliyor. Bu, büyük bir yapı uygulayarak mümkündür, ancak Fortran'da (bazı örnekler vermek için) kolayca ve yaygın olarak kullanılan regex ayrıştırıcı veya XML ayrıştırıcı kütüphanelerini görmedim. Bunun iyi bir nedeni var: Artık Fortran'ı kullanan tek kişi biziz. Belki de farklı kullanım durumlarını düşünüyoruz.
Geoff Oxberry

2

Aron'un çok kapsamlı cevabına ek olarak, scicomp.stackexchange'teki hangi programlama dilinin alacağı - hem programların hızı hem de ne kadar kolay veya zor olduğu sorusu ile ilgili çeşitli konulara bir göz atacağım. bu dillerde yazılım yazmak ve bakımını yapmaktır.

Bununla birlikte, orada yazılanlara ek olarak, birkaç gözlem yapmama izin verin:

(i) Listenize Fortran ortak dizisini dahil ettiniz. Bildiğim kadarıyla, bunu gerçekten destekleyen derleyicilerin sayısı çok az - ve aslında benim sıfırım. En yaygın olarak kullanılan Fortran derleyicisi GNU gfortran'dır ve mevcut geliştirme kaynakları bir dizi ko-diziyi ayrıştırırken, aslında hiçbirini desteklemediğine inanıyorum (yani sözdizimini kabul eder, ancak anlambilimin hiçbirini uygulamaz) . Bu elbette daha yeni Fortran standartları hakkında genel bir gözlemdir: derleyicilerin aslında yeni standartları desteklediği gecikme birkaç yıl içinde ölçülür - derleyiciler Fortran 2003'ü son birkaç yılda sadece tamamen uygular ve Fortran 2008'i kısmen destekler. Kullandığınız şeyi destekleyecek bir derleyiciniz varsa, bu işlem herhangi birini kullanmanızı engellememelidir.

(ii) C ++ / Cilk + için de aynı şey geçerlidir: Evet, Intel bunu GCC'nin bir dalında geliştiriyor, ancak GCC sürümlerinin hiçbirinde mevcut değil ve muhtemelen bir süre olmayacak. Tipik linux makinelerde kurulu GCC sürümleri ile Cilk + bulana kadar 2-3 yıl daha bekleyebilirsiniz.

(iii) C ++ / TBB farklı bir hikaye: TBB bir süredir var, çok kararlı bir arayüze sahip ve son birkaç yıldır var olan çoğu C ++ derleyicisiyle derlenebilir (linux'da ve pencerelerde) . Biz bunu kullanıyoruz deal.II iyi sonuçlarla zaten birkaç yıldır. Üzerinde çok iyi bir kitap da var.

(iv) OpenMP hakkında kendi fikrim var, yani bir problem arayışında bir çözüm. Çok düzenli veri yapılarınız varsa, ilginizi çekebilecek iç döngülerle paralel hale getirmek için iyi çalışır. Ancak, bir şeyi paralelleştirmeniz gerekiyorsa nadiren yapmak istediğiniz şeydir - çünkü gerçekten yapmak istediğiniz şey dış döngülerle paralelleştirmektir . Ve bunun için, TBB gibi çözümler çok daha iyi çözümlerdir çünkü programlama dilinin mekanizmalarını, dilin dışında neler olduğunu (#pragmas aracılığıyla) ve iplik tutamaçlarına erişemeyeceğiniz bir şekilde tanımlamak yerine kullanırlar. , sonuç durum göstergeleri vb.

(v) Deneysel iseniz, paralel programlama ve özellikle de tarif ettikleriniz gibi görevler için tasarlanmış yeni programlama dillerine de bakabilirsiniz. Bir göz atacağım iki tane var: X10 ve Şapel . Chapel hakkında güzel öğreticiler gördüm ve iyi tasarlanmış gibi görünüyor, ancak her ikisi de elbette bugün de insular çözümler.


Kayıt için Intel, mevcut derleyicilerinde paralelleştirilmiş (dağıtılmış bellek) bir Coran dizisi Fortran'a sahip olduğunu iddia ediyor. TACC'ye bakıyoruz, ancak henüz rapor edecek hiçbir şeyim yok. Cray'ın derleyicilerinde de bir uygulaması vardır, ancak bu yalnızca dünyadaki az sayıdaki makinelerde kullanılabilir. Henüz kimsenin Co-dizilerle ilgili olarak tam Fortran 2008 standardını uyguladığını düşünmüyorum, ancak birkaç derleyicide yeni başlayanlardan daha fazlası var. Elbette Cilk +, Intel derleyicileriyle de kullanılabilir, ancak güven duymak muhtemelen akıllıca değildir.
Bill Barth

Fortran 2008 standardı 2010'un sonlarına kadar onaylanmadı, bu yüzden CAF'ın yaygın olarak kullanılabilmesi birkaç yıl sürecek. G95 aslında (ücretsiz olmayan) bir uygulamaya sahipti, ancak artık geliştirilmedi (geliştirici PathScale'e katıldı).
stali

G95'in çoğu sonuçta gfortran ile sonuçlandı, ancak CAF bunun bir parçası olmayabilir.
Wolfgang Bangerth

Intel derleyicisinin ortak diziyi iyi desteklediğine inanıyorum. Bunu mpiexec kullanarak inşa ettiler. Bu benim ilk tercihim olmayacak. Güzel şey, aynı uygulamanın paylaşılan ve dağıtılmış bellekte çalışabilmesidir (birkaç test çalıştırdım). Opteron paylaşılan bellek işlemcileri gerçekten makul fiyatlarla 60 çekirdeğe ulaştığında, önce paylaşılan bellek seçeneklerimi görmek istiyorum.
electrique

2

Genel olarak, bu yazılım projesi konusunda gerçekten ciddiyseniz, kendinizi en rahat hissettiğiniz dilde tam bir yeniden yazmayı öneririm. İşi tek başına yapacağınız anlaşılıyor ve bu nedenle evde en çok hissettiğiniz dilde en iyi sonuçları alacaksınız.

Daha spesifik olarak, paralellik konusunda, kutunun dışında biraz düşünmeye çalışmanızı öneririm. OpenMP'nin güçlü yönleri vardır, ancak sıralı bir kod alma ve burada ve orada paralellik yapma fikrinde sıkışmıştır. Aynı şey, aslında, Intels TBB için de geçerli.

Cilk kesinlikle doğru yönde atılmış bir adımdır, yani probleminizi / çözümünüzü doğası gereği paralel bir düzende yeniden düşünmeye zorlar. Bununla ilgili sevmediğim şey, yine de başka bir dil olması . Ayrıca, paralel görevler arasındaki ilişkileri kabaca çıkarabileceğinden, zamanlayıcı oldukça muhafazakar olabilir ve bazı problemler için iyi ölçeklenemeyebilir.

İyi haber şu ki, yine, eğer uygulamanızla ilgili ciddi iseniz, Cilk'in yaptıklarını yapabilirsiniz, örneğin sorununuzu bir dizi bağımlı görev olarak yeniden yazabilir ve bir dizi işlemciye / pthreads kullanarak veya işlemleri oluşturmak için OpenMP'yi yanlış kullanan tek başına çekirdekler . Bunun nasıl yapılabileceğinin güzel bir örneği , PLASMA kütüphanesinde kullanılan QUARK zamanlayıcıdır . Performansının Cilk ile güzel bir karşılaştırması burada verilmiştir .


Önerilen bağlantılara bakacağım. Karşılaştırma kağıdı çok güzel! Teşekkürler! Ben pthreads hakkında düşünüyorum ama programın çapraz platform olmasını istiyorum. Bildiğim kadarıyla pthreads pencereleri altında problemleri var (yanlış?).
electrique

@ p3tris: pthreads'deki "p" POSIX içindir, bu yüzden olabildiğince taşınabilir. Proje gibi pthreads-win32veya içinde bazı uyumlu Windows uygulamaları vardır cygwin.
Pedro

Stackoverflow.com/q/2797690/801468 dayanarak kullanmak için sıralamak için gereken çok şey olduğunu görüyorum. Programcı olmadığım için daha test edilmiş bir şeye bağlı kalmayı tercih ederim.
electrique

2

Yukarıdaki yorumlarda kaba kale hakkında çok az tartışma yapılmıştır. Şu anda ve sınırlı bilgime göre, derleyicilerdeki kaba destek kabaca aşağıdaki gibidir:

  • Cray, en azından temel kaba özellikleri destekleyen bir derleyiciye sahiptir. Ben "eğitim" olması amaçlanan kod yazmak için kullandım, ama kaba fortran gerçek kod yazabilirsiniz söyleyebilirim. Sözdizimi ve kavramlar çoğunlukla MPI'dan çok daha basittir, ancak her zaman olduğu gibi, lota tuzakları vardır ve tuzaklar MPI'dan farklıdır.
  • Intel fortran, MPI kitaplıklarının üzerine inşa edilmiş kaba desteğe sahiptir. Sözde teorik zirve performanslarını sınırlıyor, ancak herhangi bir ölçüm görmedim.
  • Gfortran kabaları destekler, ancak sadece tek bir görüntü (veya MPI konuşmasında tek sıra) için. Bu nedenle, gfortran 4.8 veya 4.9 çıkana kadar gerçek bir paralelleştirme mevcut değildir.

Genel olarak, kaba bazlı bir kod başlatırken dikkatli olurum. Sözdizimi, MPI ile Fortran / C / C ++ 'dan daha basit ve çok daha uygundur, ancak daha sonra tam özellikli değildir. Örneğin, MPI sizin için çok uygun olabilecek birçok azaltma işlemini vb. Destekler . Bu gerçekten çok fazla iletişim gereksiniminize bağlı olacaktır. Bir örnek isterseniz, bana haber verin ve dosyaları kazabilsem size birkaç tane verebilirim.


Evet, kaba Fortran'ın bu tür bir soruna hazır olup olmadığı hakkında daha fazla bilgi kesinlikle yardımcı olacaktır. Scicomp'a Hoşgeldiniz!
Aron Ahmadia

1

Göz at Spark işlevsel programlama yararlanır hafızasında hesaplamalar için dağıtılmış bir çerçeve var. Spark'daki bir programın yapısı, MPI ile karşılaştırıldığında çok farklıdır, temel olarak tek bir bilgisayar gibi, otomatik olarak bellekte bulunan verilere işlev olarak dağıtılan bir kod yazarsınız. Scala, Java ve Python'u destekler.

Lojistik Regresyon (scala):

//load data to distributed memory
val points = spark.textFile(...).map(parsePoint).cache()
var w = Vector.random(D) // current separating plane
for (i <- 1 to ITERATIONS) {
  val gradient = points.map(p =>
    (1 / (1 + exp(-p.y*(w dot p.x))) - 1) * p.y * p.x
  ).reduce(_ + _)
  w -= gradient
}
println("Final separating plane: " + w)

Bazı düşük seviyeli hesaplamalar için bir Fortran kütüphanesi kullanan MLib (Machine Learning library) adlı bir uzantı var (Python için sanırım numpy kullanılıyor). Bu nedenle, fikir basittir, algoritmanıza odaklanın ve optimizasyonları daha düşük seviyelere bırakın (işleme sırası, veri dağıtımı vb.).

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.