Hesaplamalı bilimde C ++ ifade şablonlarını ne zaman kullanmalıyım ve ne zaman * kullanmamalıyım?


24

C ++ dilinde bilimsel bir kod üzerinde çalıştığımı varsayalım. Bir meslektaşı ile yakın zamanda yapılan bir tartışmada, ifade şablonlarının gerçekten kötü bir şey olabileceği, potansiyel olarak yazılımı yalnızca belirli gcc sürümlerinde derlenebilir hale getirdiği iddia edildi. Güya bu problem, Downfall'ın bu parodisinin altyazılarında olduğu gibi, birkaç bilimsel kodu etkiledi . (Bunlar benim tanıdığım tek örnek, bu yüzden bağlantı.)

Bununla birlikte, diğer insanlar, ifade şablonlarının yararlı olduğunu savundular, çünkü SIAM Bilimsel Hesaplama Dergisi'nde bu yazıda olduğu gibi , ara sonuçların geçici değişkenlerde saklanmasını önleyerek performans kazanımları sağlayabiliyorlar .

C ++ 'ta şablon metaprogramlaması hakkında pek bir şey bilmiyorum, ama otomatik farklılaşmada ve aralık aritmetikte kullanılan bir yaklaşım olduğunu biliyorum, bu şekilde ifade şablonları hakkında bir tartışmaya girdim. Hem performanstaki potansiyel avantajlar hem de bakımdaki potansiyel dezavantajlar göz önüne alındığında (doğru kelime olsa bile), hesaplama biliminde C ++ ifade şablonlarını ne zaman kullanmalıyım ve ne zaman kaçınmalıyım?


Ah, video çok komik. Var olduğunu bilmiyordum. Kim yaptı, biliyor musun?
Wolfgang Bangerth

Fikrim yok; Birkaç PETSc insanı bana bir noktada bağlantılar gönderdi. Bir FEniCS geliştiricisinin yaptığını düşünüyorum.
Geoff Oxberry

Video bağlantısı koptu ve meraktan ölüyorum. Yeni link
Praxeolitic

Oh drat, boşver, Hitler videolarımız için youtube'un geldiğini gördüm .
Praxeolitic 24/15

Yanıtlar:


17

İfade şablonlarıyla ilgili sorunum, çok sızdıran bir soyutlama olmaları. Güzel sözdizimi ile basit bir iş yapmak için çok karmaşık kod yazma çok iş harcamak. Ancak algoritmayı değiştirmek istiyorsanız, kirli kodla uğraşmak zorundasınız ve türler veya sözdizimi ile yer değiştirirseniz, tamamen anlaşılmaz hata mesajları alırsınız. Uygulamanız, ifade şablonlarını temel alan bir kitaplığa mükemmel şekilde eşleşiyorsa, dikkate değer olabilir, ancak emin değilseniz, sadece normal kod yazmanızı öneririm. Elbette, üst seviye kod daha az hoş, fakat sadece yapılması gerekenleri yapabilirsiniz. Bir avantaj olarak, derleme zamanı ve ikili büyüklükler azalır ve derleyici ve derleme bayrağı seçimi nedeniyle performansta büyük farklılıklar olması gerekmez.


Evet, bazı hata mesajlarını ilk önce gcc 2.95'den gcc 4.x'e kodlamak zorunda kaldığımda gördüm ve derleyici şablonlarla ilgili her türlü hatayı fırlattı. Bir laboratuar arkadaşım C ++ 'ta aralık aritmetiği için şablonlanmış bir kütüphane geliştiriyor (daha fazla araştırma yapmak için Boost :: Interval'da olmayan yeni özellikler eklendi) ve kodun kabus görmesini istemiyorum derlemek için.
Geoff Oxberry

12

Diğerleri, ET programlarını yazmanın ne kadar zor olduğu ve hata mesajlarını anlamanın karmaşıklığı hakkında yorum yaptılar. Derleyiciler konusunda yorum yapmama izin verin: Bir süre önce büyük sorunlardan birinin her şeyin çalışmasını ve taşınabilir bir şekilde çalışmasını sağlamak için C ++ standardına uygun bir derleyici bulmak olduğu doğru. Sonuç olarak, birçok hata bulduk - ismimde 2-300 hata raporum var, gcc, Intel icc, IBM xlC ve Portland pgicc. Sonuç olarak, deal.II yapılandırma betiği, özellikle şablonlar, arkadaş beyanları, ad alanları, vb. Alanlardaki çok sayıda derleyici hata testinin deposudur.

Ancak, derleyici üreticilerinin birlikte hareketlerini çok iyi yaptıkları ortaya çıktı: bugün, gcc ve icc bugün tüm testlerimizi geçiyor ve ikisi arasında taşınabilir kod yazmak kolaydır. PGI'nin çok geride olmadığını söyleyebilirim, ancak yıllar geçmeyecek gibi görünen bazı tuhaflıklar var. Öte yandan, xlC bambaşka bir hikaye - her 6 ayda bir hatayı düzeltirler, ancak onlarla yıllarca hata bildirimleri yapılmasına rağmen, ilerleme son derece yavaştır ve xlC hiçbir zaman anlaşma derleyemedi.

Tüm bunların anlamı şudur: İki büyük derleyiciye bağlı kalırsanız, bugün çalışmalarını bekleyebilirsiniz. Günümüzde çoğu bilgisayar ve işletim sistemi tipik olarak bunlardan en az birine sahip olduğundan, bu yeterli. İşlerin daha zor olduğu tek platform, sistem derleyicisinin tipik olarak xlC olduğu tüm hatalarıyla BlueGene'dir.


Sadece merak dışında, / xlc'deki yeni xlc derleyicilere karşı derlemeyi denediniz mi?
Aron Ahmadia 29:12

Hayır, xIC'den vazgeçtiğimi itiraf edeceğim.
Wolfgang Bangerth,

5

ET'lerle ilgili çok uzun zaman önce, sizin de belirttiğiniz gibi, derleyicilerin hala onlarla uğraştığını denedim. Blitz kütüphanesini lineer cebir için bazı kodlarımda kullandım . O zaman sorun iyi derleyiciyi elde ediyordu ve mükemmel bir C ++ programcısı olmadığım için derleyici hata mesajlarını yorumluyordum. İkincisi basitçe yönetilemezdi. Derleyici ortalama olarak yaklaşık 1000 satır hata mesajı üretecektir. Programlama hatamı çabucak bulamadım.

Oonumerics web sayfasında daha fazla bilgi bulabilirsiniz (iki ET çalışmasının süreci vardır).

Ama onlardan uzak dururdum ....


Derleyici hata mesajları gerçekten endişelerimden biri. Projelerim için kütüphaneler oluşturmak üzere derlediğim bazı şablonlanmış C ++ kodlarıyla, derleyici yüzlerce satır uyarı mesajı üretebilir. Ancak, benim kodum değil, anlamıyorum ve genel olarak konuşursak, işe yarıyor, ben de rahat bırakıyorum. Uzun, şifreli hata mesajları, hata ayıklama için iyi bir uyarı vermez.
Geoff Oxberry

4

Sorun zaten 'ifade şablonları (ET)' ile başlar. Bunun için kesin bir tanım olup olmadığını bilmiyorum. Ancak, ortak kullanımında bir şekilde 'doğrusal cebir ifadelerini nasıl kodladığınız' ve 'nasıl hesaplandığı' ile çiftleşir. Örneğin:

Vektör işlemini kodlarsınız

v = 2*x + 3*y + 4*z;                    // (1)

Ve bir döngü tarafından hesaplanır

for (int i=0; i<n; ++i)                 // (2)
    v(i) = 2*x(i) + 3*y(i) + 4*z(i);

Bence bu iki farklı şey ve ayrıştırılması gerekiyor: (1) bir arayüz ve (2) olası bir uygulama. Demek istediğim bu programlamada yaygın bir uygulamadır. Tabii (2) iyi bir varsayılan uygulama olabilir, ancak genel olarak özel ve özel bir uygulamadan yararlanmak istiyorum. Mesela ben böyle bir işlevi istiyorum

myGreatVecSum(alpha, x, beta, y, gamma, z, result);    // (3)

kodlarken (1) çağrıldım. Belki (3) sadece (2) 'deki gibi bir döngü kullanır. Ancak vektör boyutuna bağlı olarak diğer uygulamalar daha verimli olabilir. Her neyse, yüksek performansta bazı uzmanlar mümkün olduğu kadar uygulayabilir ve ayarlayabilir (3). Öyleyse, (1) (3) çağrısı ile eşlenemiyorsa, o zaman (1) 'in sözdizimsel şekerinden kaçının ve doğrudan (3)' ü doğrudan çağırın.

Tarif ettiğim yeni bir şey değil. Aksine, BLAS / LPACK'in arkasındaki fikir:

  • LAPACK'teki tüm performans kritik işlemler BLAS fonksiyonlarını çağırarak yapılır.
  • BLAS, sadece yaygın olarak ihtiyaç duyulan lineer cebir ifadeleri için bir arayüz tanımlar.
  • BLAS için farklı optimize edilmiş uygulamalar mevcuttur.

BLAS'ın kapsamı yeterli değilse (örneğin, (3) gibi bir işlev sağlamıyorsa), biri BLAS'ın kapsamını uzatabilir. Bu yüzden 60'lı ve 70'li yılların bu dinozor taş devri aracıyla ara yüz ve uygulamanın temiz ve ortogonal bir ayrıldığını fark eder. Sayısal C ++ kütüphanelerinin bu yazılım kalitesi seviyesine ulaşamaması çok komik. Her ne kadar programlama dili çok daha karmaşık olsa da. Bu nedenle, BLAS / LAPACK'in hala canlı ve aktif olarak gelişmiş olması şaşırtıcı değildir.

Yani bence ET'ler kendi başına kötü değildir. Ancak, sayısal C ++ kütüphanelerinde yaygın olarak nasıl kullanıldığı, bilimsel bilgi işlem çevrelerinde onlara çok kötü bir ün kazandı.


Michael, ifade şablonlarından birinin eksik olduğunu düşünüyorum. Kod örneğiniz (1) aslında optimize edilmiş BLAS çağrıları ile eşleşmiyor. Aslında, bir BLAS rutini mevcut olsa bile, bir BLAS işlev çağrısının tepesi küçük vektörler ve matrisler için oldukça korkunç hale getirir. Blaze ve Eigen gibi sofistike ifade şablonu kütüphaneleri, geçici kullanımdan kaçınmak için ertelenmiş ifade değerlendirmesini kullanabilir, ancak alan özeline özgü bir dilden hemen hemen hiçbir şeyin elle yuvarlanmış lineer cebiri geçemeyeceğine ikna oldum.
Aron Ahmadia 29:12

Hayır, bence noktayı kaçırıyorsun. (A) BLAS'ı sık sık ihtiyaç duyulan bazı lineer cebir işlemlerinin bir özelliği olarak ayırmanız gerekir (b) ATLAS, GotoBLAS, vb. Gibi bir BLAS uygulaması. BTW, FLENS'te nasıl çalıştığını varsayılan olarak (1) BLAS'tan üç kez axpy çağırılarak değerlendirilebilir. Fakat değiştirmeden (1) , (2) 'deki gibi değerlendirebilirim. Dolayısıyla mantıksal olan şudur: (1) 'deki gibi bir işlem önemliyse, belirtilen BLAS işlemlerinin (a) seti uzatılabilir.
Michael Lehn

Bu yüzden kilit nokta şudur: 'v = x + y + z' gibi bir gösterim ve nihayet nasıl hesaplandığı da ayrılmalıdır. Eigen, MTL, BLITZ, blaze-lib bu konuda tamamen başarısız.
Michael Lehn 29:12

1
Doğru, ancak sıkça ihtiyaç duyulan lineer cebir işlemlerinin sayısı kombinasyonlu. C ++ gibi bir dil kullanacaksanız, ertelenen değerlendirmeyi kullanarak alt blokları ve algoritmaları akıllıca birleştirerek veya büyük bir uygulama uygulayarak ifade şablonlarını kullanarak (gerektiği gibi Eigen / Blaze yaklaşımı) kullanma seçeneğiniz vardır. olası her rutinin kütüphanesi. Numba ve Cython'daki son çalışmalar Python gibi üst düzey komut dizileriyle çalışırken benzer veya daha iyi performans alabileceğimizi gösterdiği için, her iki yaklaşımı da savunmam.
Aron Ahmadia 29:12

Fakat yine de, şikayet ettiğim şey, Eigen gibi bu kadar karmaşık (karmaşık ama esnek olmayan) kitaplıkların sık sık gösterime ve değerlendirme mekanizmasına sıkı sıkıya bağlı olduklarını ve hatta bunun iyi bir şey olduğunu düşündükleri. Matlab gibi bir araç kullanırsam, sadece bir şeyleri kodlamak istiyorum ve Matlab'ın mümkün olan en iyi şeyi yaptığına güveniyorum. C ++ gibi bir dil kullanırsam kontrolde olmak istiyorum. Bu nedenle, varsayılan bir değerlendirme mekanizması varsa takdir edin, ancak bunu değiştirmek mümkün olmalıdır. Aksi halde geri dönüp doğrudan C ++ 'da fonksiyonları çağırıyorum.
Michael Lehn
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.