У мене величезна кількість функцій на загальну суму близько 2,8 Гб об'єктного коду (на жаль, немає можливості обійтись, наукові обчислення ...)
Коли я намагаюся зв'язати їх, я отримую (очікувані) relocation truncated to fit: R_X86_64_32S
помилки, які я сподівався обійти, вказавши прапор компілятора -mcmodel=medium
. Усі бібліотеки, які пов'язані крім того, якими я керую, складаються з -fpic
прапором.
Однак помилка зберігається, і я припускаю, що деякі бібліотеки, на які я посилаюся, не компілюються з PIC.
Ось помилка:
/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
І системні бібліотеки, з якими я пов'язую:
-lgfortran -lm -lrt -lpthread
Будь-які підказки, де шукати проблему?
EDIT: Перш за все, дякую за обговорення ... Щоб уточнити трохи, у мене є сотні функцій (кожен розміром приблизно 1 Мб в окремих об’єктних файлах):
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;
}
Об'єкт s
порівняно невеликий і зберігає необхідні константи x14, x15, ..., ds0, ..., і т.д., тоді як ti
лише повертає дубль із зовнішньої бібліотеки. Як бачимо, csc[]
це попередньо обчислена карта значень, яка також оцінюється в окремих файлах об'єктів (знову ж таки, сотнями розміром приблизно приблизно 1 Мб) наступної форми:
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));
}
// ...
}
Ось про це. Заключний крок тоді просто полягає у виклику всіх цих func[i]
і підбитті підсумків.
Щодо того, що це досить особливий і незвичний випадок: Так, так є. З цим доводиться справлятися людям, намагаючись робити високоточні обчислення для фізики частинок.
EDIT2: Я також повинен додати, що x12, x13 тощо, насправді не є константами. Вони встановлюються на конкретні значення, всі ці функції запускаються і результат повертається, а потім вибирається новий набір x12, x13 і т.д. для отримання наступного значення. І це потрібно зробити 10 ^ 5 - 10 ^ 6 разів ...
EDIT3: Дякую за пропозиції та обговорення досі ... Я спробую якось згорнути петлі при генерації коду, не знаю, як це точно зробити, якщо чесно, але це найкраща ставка.
До речі, я не намагався сховатися за "це наукові обчислення - ніякого способу оптимізації". Просто основа цього коду - це те, що виходить із "чорної скриньки", до якої я не маю реального доступу, і, тим більше, все це чудово спрацювало з простими прикладами, і я в основному відчуваю, що переповнюється тим, що відбувається в реальному світовий додаток ...
EDIT4: Отже, мені вдалося зменшити розмір коду csc
визначень приблизно на четверте, спростивши вирази в системі комп’ютерної алгебри ( Mathematica ). Зараз я бачу певний спосіб зменшити його на інший порядок, застосувавши деякі інші хитрощі перед створенням коду (який би звів цю частину приблизно до 100 Мб), і я сподіваюся, що ця ідея спрацює.
Тепер пов’язані з вашими відповідями: я намагаюся знову повернути петлі назад у func
s, де CAS не дуже допоможе, але у мене вже є деякі ідеї. Наприклад, сортуючи вирази за змінними типу x12, x13,...
, розбираємо csc
s з Python та генеруємо таблиці, що пов'язують їх між собою. Тоді я можу принаймні генерувати ці частини як петлі. Оскільки це здається найкращим рішенням поки що, я відзначаю це як найкращу відповідь.
Однак я хотів би також дати кредит VJo. GCC 4.6 справді працює набагато краще, створює менший код і швидший. Використання великої моделі працює за таким кодом, як є. Тож технічно це правильна відповідь, але змінити цілу концепцію - набагато кращий підхід.
Дякую всім за ваші пропозиції та допомогу. Якщо хтось зацікавлений, я збираюся опублікувати остаточний результат, як тільки я буду готовий.
ЗАМОВЛЕННЯ. Лише деякі зауваження до деяких інших відповідей: Код, який я намагаюся запустити, не виникає в результаті розширення простих функцій / алгоритмів і нерозумної непотрібної розгортання. Що насправді відбувається, це те, що матеріал, з якого ми починаємо, є досить складними математичними об'єктами, і приведення їх у числово- обчислювальну форму породжує ці вирази. Проблема полягає фактично в основній фізичній теорії. Складність проміжних виразів масштабується фактично, що добре відомо, але, поєднуючи все це з чимось фізично вимірюваним - спостережуваним, воно просто зводиться до лише декількох дуже малих функцій, що складають основу виразів. (У цьому відношенні, безумовно, є щось "неправильне" із загальним і доступним лише для цьогоansatz, яку називають "теорією збурень") Ми намагаємось вивести цей ансац на інший рівень, який вже не є аналітичним, і де основи необхідних функцій не відомі. Тож ми намагаємось це жорстоко змусити. Не найкращий спосіб, але, сподіваємось, той, хто допомагає в нашому розумінні фізики під рукою врешті ...
ОСТАННЕ ВИДАЛЕННЯ:
Завдяки всім вашим пропозиціям мені вдалося значно зменшити розмір коду, використовуючи Mathematica та модифікацію генератора коду для func
s дещо уздовж рядків верхньої відповіді :)
Я спростив csc
функції з Mathematica, знизивши її до 92 МБ. Це непридатна частина. Перші спроби тривали назавжди, але після деяких оптимізацій це зараз проходить приблизно за 10 хвилин на одному процесорі.
Вплив на func
s було драматичним: весь розмір коду для них зменшився приблизно до 9 Мб, тому код тепер налічується в діапазоні 100 Мб. Тепер є сенс увімкнути оптимізацію, і виконання відбувається досить швидко.
Ще раз дякую всім за ваші пропозиції, я багато чого навчився.
mmap
цього самостійно із зовнішнього бінарного файлу під час виконання.