Toplam 2,8 GB nesne koduna sahip çok sayıda işleve sahibim (maalesef bunun yolu yok, bilimsel hesaplama ...)
Onları bağlamayı denediğimde relocation truncated to fit: R_X86_64_32S
, derleyici bayrağını belirterek atlatmayı umduğum (beklenen) hatalar alıyorum -mcmodel=medium
. Bağlantılı olan ve benim kontrolümde olan tüm kitaplıklar -fpic
bayrakla derleniyor .
Yine de hata devam ediyor ve bağlantı kurduğum bazı kitaplıkların PIC ile derlenmediğini varsayıyorum.
İşte hata:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x12): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_fini' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x19): relocation truncated to fit: R_X86_64_32S against symbol `__libc_csu_init' defined in .text section in /usr/lib64/libc_nonshared.a(elf-init.oS)
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../lib64/crti.o: In function `call_gmon_start':
(.text+0x7): relocation truncated to fit: R_X86_64_GOTPCREL against undefined symbol `__gmon_start__'
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtbegin.o: In function `__do_global_dtors_aux':
crtstuff.c:(.text+0xb): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x13): relocation truncated to fit: R_X86_64_32 against symbol `__DTOR_END__' defined in .dtors section in /usr/lib/gcc/x86_64-redhat-linux/4.1.2/crtend.o
crtstuff.c:(.text+0x19): relocation truncated to fit: R_X86_64_32S against `.dtors'
crtstuff.c:(.text+0x28): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x38): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x3f): relocation truncated to fit: R_X86_64_32S against `.dtors'
crtstuff.c:(.text+0x46): relocation truncated to fit: R_X86_64_PC32 against `.bss'
crtstuff.c:(.text+0x51): additional relocation overflows omitted from the output
collect2: ld returned 1 exit status
make: *** [testsme] Error 1
Ve bağladığım sistem kitaplıkları:
-lgfortran -lm -lrt -lpthread
Sorunu nerede arayacağınıza dair bir ipucu var mı?
DÜZENLEME: Öncelikle, tartışma için teşekkür ederim ... Biraz açıklığa kavuşturmak için, yüzlerce işlevim var (her biri ayrı nesne dosyalarında yaklaşık 1 MB boyutunda) şöyle:
double func1(std::tr1::unordered_map<int, double> & csc,
std::vector<EvaluationNode::Ptr> & ti,
ProcessVars & s)
{
double sum, prefactor, expr;
prefactor = +s.ds8*s.ds10*ti[0]->value();
expr = ( - 5/243.*(s.x14*s.x15*csc[49300] + 9/10.*s.x14*s.x15*csc[49301] +
1/10.*s.x14*s.x15*csc[49302] - 3/5.*s.x14*s.x15*csc[49303] -
27/10.*s.x14*s.x15*csc[49304] + 12/5.*s.x14*s.x15*csc[49305] -
3/10.*s.x14*s.x15*csc[49306] - 4/5.*s.x14*s.x15*csc[49307] +
21/10.*s.x14*s.x15*csc[49308] + 1/10.*s.x14*s.x15*csc[49309] -
s.x14*s.x15*csc[51370] - 9/10.*s.x14*s.x15*csc[51371] -
1/10.*s.x14*s.x15*csc[51372] + 3/5.*s.x14*s.x15*csc[51373] +
27/10.*s.x14*s.x15*csc[51374] - 12/5.*s.x14*s.x15*csc[51375] +
3/10.*s.x14*s.x15*csc[51376] + 4/5.*s.x14*s.x15*csc[51377] -
21/10.*s.x14*s.x15*csc[51378] - 1/10.*s.x14*s.x15*csc[51379] -
2*s.x14*s.x15*csc[55100] - 9/5.*s.x14*s.x15*csc[55101] -
1/5.*s.x14*s.x15*csc[55102] + 6/5.*s.x14*s.x15*csc[55103] +
27/5.*s.x14*s.x15*csc[55104] - 24/5.*s.x14*s.x15*csc[55105] +
3/5.*s.x14*s.x15*csc[55106] + 8/5.*s.x14*s.x15*csc[55107] -
21/5.*s.x14*s.x15*csc[55108] - 1/5.*s.x14*s.x15*csc[55109] -
2*s.x14*s.x15*csc[55170] - 9/5.*s.x14*s.x15*csc[55171] -
1/5.*s.x14*s.x15*csc[55172] + 6/5.*s.x14*s.x15*csc[55173] +
27/5.*s.x14*s.x15*csc[55174] - 24/5.*s.x14*s.x15*csc[55175] +
// ...
;
sum += prefactor*expr;
// ...
return sum;
}
Nesne s
nispeten küçüktür ve gerekli x14, x15, ..., ds0, ... vb. Sabitleri korurken, ti
harici bir kitaplıktan bir double döndürür. Gördüğünüz gibi csc[]
, aşağıdaki formdaki ayrı nesne dosyalarında (yine her biri yaklaşık 1 MB boyutunda yüzlerce) değerlendirilen önceden hesaplanmış bir değer haritasıdır:
void cscs132(std::tr1::unordered_map<int,double> & csc, ProcessVars & s)
{
{
double csc19295 = + s.ds0*s.ds1*s.ds2 * ( -
32*s.x12pow2*s.x15*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x15*s.x35*s.x45*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12pow2*s.x25*s.x35*s.x45*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.mbpow4*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.x35*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x34*s.x45*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35*s.mbpow4*s.mWpowinv2 +
32*s.x12pow2*s.x35pow2*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35pow2*s.x45*s.mWpowinv2 +
64*s.x12pow2*s.x35*s.x45*s.mbpow2*s.mWpowinv2 +
32*s.x12pow2*s.x35*s.x45pow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.mbpow4*s.mWpowinv2 +
64*s.x12*s.p1p3*s.x15pow2*s.mbpow2*s.mWpowinv2 +
96*s.x12*s.p1p3*s.x15*s.x25*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.p1p3*s.x15*s.x45*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.mbpow4*s.mWpowinv2 +
32*s.x12*s.p1p3*s.x25pow2*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.x35*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x25*s.x45*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.p1p3*s.x45*s.mbpow2 +
64*s.x12*s.x14*s.x15pow2*s.x35*s.mWpowinv2 +
96*s.x12*s.x14*s.x15*s.x25*s.x35*s.mWpowinv2 +
32*s.x12*s.x14*s.x15*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x15*s.x35*s.mbpow2*s.mWpowinv2 -
64*s.x12*s.x14*s.x15*s.x35pow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x15*s.x35*s.x45*s.mWpowinv2 +
32*s.x12*s.x14*s.x25pow2*s.x35*s.mWpowinv2 +
32*s.x12*s.x14*s.x25*s.x34*s.mbpow2*s.mWpowinv2 -
32*s.x12*s.x14*s.x25*s.x35pow2*s.mWpowinv2 -
// ...
csc.insert(cscMap::value_type(192953, csc19295));
}
{
double csc19296 = // ... ;
csc.insert(cscMap::value_type(192956, csc19296));
}
// ...
}
Bu onunla ilgili. Son adım daha sonra tüm bunları çağırmak func[i]
ve sonucu toplamaktan ibarettir .
Bunun oldukça özel ve alışılmadık bir durum olduğu gerçeğine gelince: Evet, öyle. İnsanların parçacık fiziği için yüksek hassasiyetli hesaplamalar yapmaya çalışırken baş etmesi gereken şey budur.
DÜZENLEME2: Ayrıca x12, x13, vs.'nin gerçekten sabit olmadığını da eklemeliyim. Belirli değerlere ayarlanırlar, tüm bu işlevler çalıştırılır ve sonuç döndürülür ve ardından bir sonraki değeri üretmek için yeni bir x12, x13 vb. Kümesi seçilir. Ve bu 10 ^ 5 ila 10 ^ 6 kez yapılmalıdır ...
DÜZENLEME3: Şimdiye kadarki öneriler ve tartışma için teşekkür ederim ... Dürüst olmak gerekirse, bunu tam olarak nasıl yapacağımı bilmiyorum, ama bu en iyi bahis.
BTW, "bu bilimsel bilgi işlem - optimize etmenin yolu yok" arkasına saklanmaya çalışmadım. Sadece bu kodun temeli, gerçek erişimim olmayan bir "kara kutu" dan çıkan bir şeydir ve dahası, her şey basit örneklerle harika çalıştı ve esas olarak gerçek hayatta olanlarla boğulmuş hissediyorum. dünya uygulaması ...
EDIT4: Böylece, csc
bir bilgisayar cebir sistemindeki ( Mathematica ) ifadeleri basitleştirerek tanımların kod boyutunu yaklaşık dörtte bir oranında azaltmayı başardım . Şimdi, kodu oluşturmadan önce başka numaralar uygulayarak (bu bölümü yaklaşık 100 MB'ye indirecek) başka bir büyüklük sırası kadar azaltmanın bir yolunu da görüyorum ve umarım bu fikir işe yarar.
Şimdi yanıtlarınızla ilgili olarak: func
Bir CAS'ın pek yardımcı olmayacağı durumlarda döngüleri tekrar yukarı döndürmeye çalışıyorum , ancak zaten bazı fikirlerim var. Örneğin, ifadeleri değişkenlere göre sıralamak x12, x13,...
, s'leri csc
Python ile ayrıştırmak ve bunları birbiriyle ilişkilendiren tablolar oluşturmak. O zaman en azından bu parçaları döngü olarak oluşturabilirim. Bu şimdiye kadarki en iyi çözüm gibi göründüğünden, bunu en iyi cevap olarak işaretliyorum.
Bununla birlikte, VJo'ya da kredi vermek istiyorum. GCC 4.6 gerçekten çok daha iyi çalışır , daha küçük kodlar üretir ve daha hızlıdır. Büyük modeli kullanmak kodda olduğu gibi çalışır. Yani teknik olarak bu doğru cevap, ancak tüm konsepti değiştirmek çok daha iyi bir yaklaşım.
Önerileriniz ve yardımlarınız için hepinize teşekkür ederim. İlgilenen varsa, hazır olur olmaz nihai sonucu yayınlayacağım.
AÇIKLAMALAR: Bazı diğer yanıtlara birkaç açıklama: Çalıştırmaya çalıştığım kod, basit işlevlerin / algoritmaların genişlemesinden ve aptalca gereksiz kaydırmadan kaynaklanmıyor. Aslında olan şey, başladığımız şeyin oldukça karmaşık matematiksel nesneler olması ve onları sayısal olarak hesaplanabilir bir biçime getirmenin bu ifadeleri oluşturmasıdır. Sorun aslında temelde yatan fiziksel teoride yatıyor. Ara ifadelerin karmaşıklığı faktöriyel olarak ölçeklenir, ki bu gayet iyi bilinmektedir, ancak tüm bunları fiziksel olarak ölçülebilen bir şeyle (gözlemlenebilir) birleştirirken, ifadelerin temelini oluşturan yalnızca bir avuç çok küçük işleve indirgenir. (Bu konuda kesinlikle "yanlış" bir şey var ve yalnızca mevcut"pertürbasyon teorisi" olarak adlandırılan ansatz ) Bu ansatz'ı, analitik olarak artık mümkün olmayan ve ihtiyaç duyulan fonksiyonların temelinin bilinmediği başka bir seviyeye getirmeye çalışıyoruz. Biz de bu şekilde kaba kuvvet yapmaya çalışıyoruz. En iyi yol değil, ama umarım sonunda elimizdeki fizik anlayışımıza yardımcı olacak bir yol ...
SON DÜZENLEME:
Tüm önerilerinize teşekkürler, Mathematica kullanarak kod boyutunu önemli ölçüde küçültmeyi başardım ve kod üretecinin func
en iyi cevabın satırları boyunca biraz değiştirilmesini başardım :)
csc
Mathematica ile fonksiyonları basitleştirip 92 MB'a düşürdüm. Bu indirgenemez kısım. İlk denemeler sonsuza kadar sürdü, ancak bazı optimizasyonlardan sonra bu artık tek bir CPU'da yaklaşık 10 dakika içinde çalışıyor.
E'ler üzerindeki etkisi func
dramatikti: Bunlar için tüm kod boyutu yaklaşık 9 MB'a düştü, bu nedenle kod artık 100 MB aralığında toplanıyor. Şimdi optimizasyonları açmak mantıklı ve yürütme oldukça hızlı.
Hepinize önerileriniz için tekrar teşekkür ederim, çok şey öğrendim.
mmap
çalışma zamanında harici bir ikili dosyadan kendiniz taşımalısınız.