Hesaplamalı bir bilim insanının kendi std :: complex sürümünü uygulamasına neden ihtiyacı var?


14

Eigen , Trilinos ve deal.II gibi hesaplama bilimindeki daha iyi bilinen C ++ kitaplıklarının çoğu , std::complex<>karmaşık kayan noktalı sayıları temsil etmek için standart C ++ şablon başlık kitaplığı nesnesini kullanır.

Jack Poulson'un varsayılan kurucularla ilgili bir soruya cevabındastd::complex , Elemental'de "birkaç nedenden ötürü" kendi uygulamasına sahip olduğuna dikkat çekiyor . Bu nedenler neler? Bu yaklaşımın avantajları ve dezavantajları nelerdir?

Yanıtlar:


16

Bu tartışmanın PETSc listesinde birkaç kez ortaya çıktığını düşünüyorum. Ana nedenlerim:

  1. C ++ standardı, std :: complex'in yalnızca float, double ve long double datatypes için tanımlandığını belirtir. Böylece, dört hassasiyet gibi diğer veri türleri için kullanılamaz.

  2. Standart, karmaşık aritmetiğin kararlılığı hakkında hiçbir garanti vermez.

  3. Standart, bir std :: kompleksindeki verilerin gerçek bileşen olarak ve ardından hayali bileşen olarak depolandığını garanti etmez. Bu, BLAS ve LAPACK gibi harici kütüphanelerle arayüzler için çok önemlidir. Tüm büyük uygulamalar için doğrudur, ancak bunu sağlamayı tercih ederim.

  4. Gerçek ve hayali bileşenleri doğrudan manipüle etmeyi tercih ederim. std :: complex bunu gereksiz yere zorlaştırır.

  5. Sonunda sadece veri türü bir alan yerine bir halka olmasını gerektiren daha genel bir sürümüne sahip olmak istiyorum. Buna Gauss tam sayıları da dahildir.


6
Nokta 3, C ++ 11'de ele alınmıştır. 26.4.4 durumları, eğer ztipi bir lvalue ifadesidir cv std::complex<T> sonra reinterpret_cast<cv T(&)[2]>(z)ve reinterpret_cast<cv T(&)[2]>(z)[0]gerçek bölümünü belirler zve reinterpret_cast<cv T(&)[2]>(z)[1]sanal kısmını tayin eder z. Karmaşık sayı dizileri de ele alınmaktadır.
James Custer

3
@CamesCuster: Sonunda C ++ 11'e geçiyorum, ancak yarı egzotik mimarilere taşınabilir kalmak isteyen bilimsel kodların muhtemelen en az iki ila üç yıl daha beklemesi gerekecek. Ayrıca, C ++ 11 maalesef sorunun sadece bir kısmını ele almaktadır.
Jack Poulson

Anlıyorum, gelecekte birisinin bu soruya bakması durumunda onu oraya atıyordum.
James Custer

2
Derleyicilerin C ++ 11'i desteklemesini beklemek zorunda olduğunuzu söylemek için bir cop-out olduğunu düşünüyorum. Açık gereksinim yeni standarda getirildi çünkü mevcut tüm uygulamalar zaten onu destekliyor. Ben zaten varolan derleyiciler / kütüphanelerde bu düzeni kabul etmenin güvenli olmadığı bir durum düşünemiyorum, çünkü std :: complex'i başka bir şekilde uygulamak hiç mantıklı olmazdı.
Wolfgang Bangerth

1
@ WolfgangBangerth: Daha çok C ++ 11'e geçiş hakkında genel bir yorum yapıldı. Her iki durumda da, C ++ 11, std :: complex ile ilgili sorunların çoğunu düzeltmez.
Jack Poulson

7

std::complex<>Programlarımda kullanıyorum ve her yeni derleyici veya derleyici yükseltmesi için derleyici bayrakları ve geçici çözümlerle savaşmam gerekiyor. Bu kavgaları kronolojik sırayla anlatmaya çalışacağım:

  1. std::norm|z|2|z|-ffast-math
  2. Linux (veya linker) üzerindeki intel icc derleyicisi, std::argbelirli yapılandırmalar altında isteğe bağlı olmayan bir şekilde derlenmiştir (belirli bir gcc sürümüyle bağlantı uyumluluğu). Sorun çok sık ortaya çıktı, bu yüzden std::argdeğiştirilmesi gerekiyordu atan2(imag(),real()). Ancak yeni kod yazarken bunu unutmak çok kolaydı.
  3. Tip std::complexC99-inşa karmaşık tür farklı çağrı kuralları (= ABI) kullanır ve yerleşik yeni gcc alternatifler Fortran karmaşık tür.
  4. -ffast-mathBeklenmedik şekillerde noktası istisnalar yüzen maddenin tutulmasına derleme bayrak etkileşir. Olan şey, derleyicinin bölümleri döngülerden çıkarması ve böylece division by zeroçalışma zamanında istisnalara neden olmasıdır . Bu istisnalar hiçbir zaman döngü içinde gerçekleşmezdi, çünkü karşılık gelen bölünme, çevredeki mantık nedeniyle gerçekleşmedi. Bu gerçekten kötüydü, çünkü kayan nokta istisna teslimini (farklı derleme bayrakları kullanarak) kullanan ve bu sorunlara (ilgili ekipler dünyanın farklı yerlerinde oturuyordu) programdan ayrı olarak derlenmiş bir kütüphane idi. bu sorun gerçekten kötü sorunlara neden oldu). Bu, derleyici tarafından elle kullanılan optimizasyonu daha dikkatli yaparak çözüldü.
  5. Kütüphane programın bir parçası oldu ve artık -ffast-mathderleme bayrağını kullanmadı. Daha yeni bir gcc sürümüne yükselttikten sonra, performans büyük bir faktör tarafından düştü. Bu konuyu henüz detaylı olarak araştırmadım, ancak bunun C99 Ek G ile ilgili olduğundan korkuyorum . İtiraf etmeliyim ki, karmaşık sayılar için bu garip çarpma tanımıyla kafam karıştı ve diğer sürümlerin yanlış yönlendirildiği iddiaları ile bunun farklı versiyonları var gibi görünüyor. Umarım -fcx-limited-rangederleme bayrağı sorunu çözer, çünkü -ffast-mathbu yeni gcc sürümü ile ilgili başka bir sorun var gibi görünüyor .
  6. -ffast-mathDerleme bayrak davranışını yapar NaNgcc yeni sürümlerini tamamen öngörülemeyen (hatta isnanetkilenir). Tek çözüm NaN, programın varlığının amacını bozan herhangi bir oluşumundan kaçınmak gibi görünüyor NaN.

Şimdi yerleşik karmaşık türleri ve std::complexbu nedenlerden vazgeçmeyi planlayıp planlamadığımı sorabilirsiniz . C ++ ile kaldığım sürece yerleşik tiplerle kalacağım. C ++ 'ın bilimsel hesaplama için tamamen kullanılamaz hale gelmesi durumunda, bilimsel hesaplama ile ilgili konulara daha fazla önem veren bir dile geçmeyi tercih ederim.


Görünüşe göre C99 Ek G ile ilgili korkularım gerçekleşti ve -fcx-sınırlı aralık, karmaşık sayıları çarparken iyi hesaplama hızı için artık gerekli. En azından şu son savaş hikayesinden aldığım şey bu
Thomas Klimpel
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.