Ho un numero enorme di funzioni per un totale di circa 2,8 GB di codice oggetto (sfortunatamente non c'è niente da fare, calcolo scientifico ...)
Quando provo a collegarli, ottengo relocation truncated to fit: R_X86_64_32Serrori (previsti) , che speravo di aggirare specificando il flag del compilatore -mcmodel=medium. Tutte le librerie collegate in aggiunta alle quali ho il controllo vengono compilate con il -fpicflag.
Tuttavia, l'errore persiste e presumo che alcune librerie a cui mi collego non siano compilate con PIC.
Ecco l'errore:
/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
E le librerie di sistema a cui mi collego contro:
-lgfortran -lm -lrt -lpthread
Qualche indizio su dove cercare il problema?
EDIT: Prima di tutto, grazie per la discussione ... Per chiarire un po ', ho centinaia di funzioni (ciascuna di circa 1 MB di dimensione in file oggetto separati) come questa:
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;
}
L'oggetto sè relativamente piccolo e mantiene le costanti necessarie x14, x15, ..., ds0, ..., ecc. Mentre tirestituisce solo un double da una libreria esterna. Come puoi vedere, csc[]è una mappa di valori precalcolata che viene anche valutata in file oggetto separati (di nuovo centinaia con circa ~ 1 MB di dimensione ciascuno) della seguente forma:
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));
}
// ...
}
Questo è tutto. Il passaggio finale quindi consiste solo nel chiamare tutti quelli func[i]e sommare il risultato.
Riguardo al fatto che questo è un caso piuttosto speciale e insolito: Sì, lo è. Questo è ciò che le persone devono affrontare quando cercano di eseguire calcoli ad alta precisione per la fisica delle particelle.
EDIT2: dovrei anche aggiungere che x12, x13, ecc. Non sono realmente costanti. Sono impostati su valori specifici, tutte quelle funzioni vengono eseguite e il risultato restituito, quindi viene scelto un nuovo set di x12, x13, ecc. Per produrre il valore successivo. E questo deve essere fatto da 10 ^ 5 a 10 ^ 6 volte ...
EDIT3: Grazie per i suggerimenti e la discussione fino ad ora ... cercherò di tirare su i loop sulla generazione del codice in qualche modo, non sono sicuro di come farlo esattamente, ad essere onesti, ma questa è la scommessa migliore.
A proposito, non ho cercato di nascondermi dietro "questo è calcolo scientifico - nessun modo per ottimizzare". È solo che la base di questo codice è qualcosa che esce da una "scatola nera" a cui non ho accesso reale e, inoltre, il tutto ha funzionato alla grande con esempi semplici e mi sento principalmente sopraffatto da ciò che accade in un applicazione mondiale ...
EDIT4: Quindi, sono riuscito a ridurre la dimensione del codice delle cscdefinizioni di circa un quarto semplificando le espressioni in un sistema di computer algebra ( Mathematica ). Ora vedo anche un modo per ridurlo di un altro ordine di grandezza o giù di lì applicando alcuni altri trucchi prima di generare il codice (che porterebbe questa parte a circa 100 MB) e spero che questa idea funzioni.
Ora relativo alle tue risposte: sto cercando di ripristinare nuovamente i loop in funcs, dove un CAS non aiuta molto, ma ho già alcune idee. Ad esempio, ordinando le espressioni in base a variabili come x12, x13,..., analizza le cscs con Python e genera tabelle che le mettono in relazione tra loro. Quindi posso almeno generare queste parti come loop. Poiché questa sembra essere la soluzione migliore finora, la contrassegno come la migliore risposta.
Tuttavia, vorrei dare credito anche a VJo. GCC 4.6 funziona davvero molto meglio, produce codice più piccolo ed è più veloce. L'uso del modello grande funziona con il codice così com'è. Quindi tecnicamente questa è la risposta corretta, ma cambiare l'intero concetto è un approccio molto migliore.
Grazie a tutti per i vostri suggerimenti e aiuto. Se qualcuno è interessato, pubblicherò il risultato finale non appena sarò pronto.
OSSERVAZIONI: solo alcune osservazioni per alcune altre risposte: il codice che sto cercando di eseguire non ha origine da un'espansione di semplici funzioni / algoritmi e da stupidi e inutili srotoli. Quello che realmente accade è che le cose con cui iniziamo sono oggetti matematici piuttosto complicati e portarli in una forma numericamente computabile genera queste espressioni. Il problema sta in realtà nella teoria fisica sottostante. La complessità delle espressioni intermedie scala fattorialmente, il che è ben noto, ma quando si combina tutto questo a qualcosa di misurabile fisicamente - un osservabile - si riduce solo a una manciata di funzioni molto piccole che costituiscono la base delle espressioni. (C'è sicuramente qualcosa di "sbagliato" in questo senso con il generale e solo disponibileansatz che si chiama "teoria delle perturbazioni") Cerchiamo di portare questa ansatz ad un altro livello, che non è più fattibile analiticamente e dove non si conosce la base delle funzioni necessarie. Quindi proviamo a forzare in questo modo. Non il modo migliore, ma si spera che aiuti con la nostra comprensione della fisica a portata di mano alla fine ...
ULTIMA MODIFICA:
Grazie a tutti i tuoi suggerimenti, sono riuscito a ridurre notevolmente la dimensione del codice, utilizzando Mathematica e una modifica del generatore di codice per funcs un po 'sulla falsariga della risposta in alto :)
Ho semplificato le cscfunzioni con Mathematica, portandole a 92 MB. Questa è la parte irriducibile. I primi tentativi sono durati un'eternità, ma dopo alcune ottimizzazioni questo ora viene eseguito in circa 10 minuti su una singola CPU.
L'effetto sui messaggi di posta funcelettronica è stato drammatico: l'intera dimensione del codice è ridotta a circa 9 MB, quindi il codice ora ammonta a un totale di 100 MB. Ora ha senso attivare le ottimizzazioni e l'esecuzione è abbastanza veloce.
Ancora grazie a tutti per i vostri suggerimenti, ho imparato molto.
mmapda un binario esterno in fase di esecuzione.