Mam ogromną liczbę funkcji w sumie około 2,8 GB kodu wynikowego (niestety nie ma sposobu obejścia, obliczenia naukowe ...)
Kiedy próbuję je połączyć, otrzymuję (oczekiwane) relocation truncated to fit: R_X86_64_32S
błędy, które miałem nadzieję ominąć, określając flagę kompilatora -mcmodel=medium
. Wszystkie biblioteki połączone dodatkowo, nad którymi mam kontrolę, są kompilowane z -fpic
flagą.
Mimo to błąd nadal występuje i zakładam, że niektóre biblioteki, do których odsyłam, nie są skompilowane za pomocą PIC.
Oto błąd:
/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
Biblioteki systemowe, do których odsyłam:
-lgfortran -lm -lrt -lpthread
Jakieś wskazówki, gdzie szukać problemu?
EDYCJA: Przede wszystkim dziękuję za dyskusję ... Aby trochę wyjaśnić, mam setki funkcji (każda o rozmiarze około 1 MB w oddzielnych plikach obiektowych), takich jak:
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;
}
Obiekt s
jest stosunkowo mały i zachowuje potrzebne stałe x14, x15, ..., ds0, ... itd., A ti
po prostu zwraca double z zewnętrznej biblioteki. Jak widać, csc[]
jest to wstępnie obliczona mapa wartości, która jest również oceniana w oddzielnych plikach obiektowych (ponownie setkach po około 1 MB każdy) o następującej postaci:
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));
}
// ...
}
O to chodzi. Ostatnim krokiem jest wtedy po prostu wywołanie wszystkich func[i]
i podsumowanie wyniku.
Jeśli chodzi o fakt, że jest to raczej szczególny i nietypowy przypadek: Tak, jest. To jest to, z czym ludzie muszą sobie radzić, próbując wykonać bardzo precyzyjne obliczenia dla fizyki cząstek elementarnych.
EDIT2: Powinienem też dodać, że x12, x13 itd. Nie są tak naprawdę stałymi. Są one ustawiane na określone wartości, wszystkie te funkcje są uruchamiane i zwracany jest wynik, a następnie wybierany jest nowy zestaw x12, x13 itd., Aby wygenerować następną wartość. I trzeba to zrobić 10 ^ 5 do 10 ^ 6 razy ...
EDIT3: Dziękuję za sugestie i dotychczasową dyskusję ... Spróbuję jakoś zwinąć pętle po wygenerowaniu kodu, nie jestem pewien, jak to dokładnie, szczerze mówiąc, ale to najlepszy wybór.
Swoją drogą, nie próbowałem się ukrywać za „to jest obliczenia naukowe - nie ma sposobu na optymalizację”. Tyle, że podstawą tego kodu jest coś, co wychodzi z „czarnej skrzynki”, do której nie mam realnego dostępu, a ponadto całość działała świetnie na prostych przykładach i głównie czuję się przytłoczony tym, co dzieje się w prawdziwym aplikacja światowa ...
EDIT4: Więc udało mi się zmniejszyć rozmiar kodu csc
definicji o około jedną czwartą, upraszczając wyrażenia w systemie algebry komputerowej ( Mathematica ). Widzę teraz również sposób na zmniejszenie go o inny rząd wielkości, stosując kilka innych sztuczek przed wygenerowaniem kodu (co zmniejszyłoby tę część do około 100 MB) i mam nadzieję, że ten pomysł zadziała.
Teraz związane z twoimi odpowiedziami: próbuję ponownie zwinąć pętle w func
s, gdzie CAS niewiele pomoże, ale mam już kilka pomysłów. Na przykład, sortując wyrażenia według zmiennych, takich jak x12, x13,...
, przeanalizuj je csc
w Pythonie i wygeneruj tabele, które będą ze sobą powiązane. Następnie mogę przynajmniej wygenerować te części jako pętle. Ponieważ wydaje się, że jest to do tej pory najlepsze rozwiązanie, oznaczam to jako najlepszą odpowiedź.
Chciałbym jednak również wyrazić uznanie dla VJo. GCC 4.6 rzeczywiście działa znacznie lepiej, tworzy mniejszy kod i jest szybsze. Korzystanie z dużego modelu działa w kodzie takim, jakim jest. Więc technicznie jest to poprawna odpowiedź, ale zmiana całej koncepcji jest znacznie lepszym podejściem.
Dziękuję wszystkim za sugestie i pomoc. Jeśli ktoś jest zainteresowany, opublikuję ostateczny wynik, gdy tylko będę gotowy.
UWAGI: Kilka uwag do innych odpowiedzi: Kod, który próbuję uruchomić, nie pochodzi z rozszerzenia prostych funkcji / algorytmów i głupiego, niepotrzebnego rozwijania. W rzeczywistości dzieje się tak, że rzeczy, od których zaczynamy, to dość skomplikowane obiekty matematyczne i doprowadzenie ich do postaci obliczalnej numerycznie generuje te wyrażenia. Problem tkwi w rzeczywistości w podstawowej teorii fizycznej. Złożoność wyrażeń pośrednich skaluje się silnie, co jest dobrze znane, ale gdy łączymy wszystkie te rzeczy w coś fizycznie mierzalnego - obserwowalnego - sprowadza się to tylko do kilku bardzo małych funkcji, które stanowią podstawę wyrażeń. (Zdecydowanie jest coś „nie tak” w tym względzie z ogólnym i dostępnym tylkoansatz, który jest nazywany „teorią perturbacji”). Próbujemy przenieść ten ansatz na inny poziom, który nie jest już wykonalny analitycznie i gdzie nie są znane podstawy potrzebnych funkcji. Więc próbujemy to brutalnie wymusić w ten sposób. Nie jest to najlepszy sposób, ale miejmy nadzieję, że taki, który w końcu pomoże nam w zrozumieniu fizyki ...
OSTATNIA EDYCJA:
Dzięki wszystkim waszym sugestiom udało mi się znacznie zmniejszyć rozmiar kodu, używając Mathematica i modyfikacji generatora kodu dla func
s, nieco zgodnej z górną odpowiedzią :)
Uprościłem csc
funkcje w Mathematica, zmniejszając je do 92 MB. To jest nieredukowalna część. Pierwsze próby trwały wieki, ale po kilku optymalizacjach trwa to teraz w ciągu około 10 minut na jednym procesorze.
Wpływ na func
s był dramatyczny: cały rozmiar kodu dla nich spadł do około 9 MB, więc teraz kod zawiera się w zakresie 100 MB. Teraz warto włączyć optymalizacje, a wykonanie jest dość szybkie.
Jeszcze raz dziękuję wszystkim za sugestie, wiele się nauczyłem.
mmap
tego samodzielnie z zewnętrznego pliku binarnego w czasie wykonywania.