У меня есть огромное количество функций на общую сумму около 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
просто возвращает double из внешней библиотеки. Как вы можете видеть, 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
с помощью Python и генерации таблиц, которые связывают их друг с другом. Тогда я могу по крайней мере сгенерировать эти части как петли. Поскольку это, кажется, лучшее решение до сих пор, я считаю это лучшим ответом.
Однако я хотел бы также отдать должное VJo. GCC 4.6 действительно работает намного лучше, производит меньший код и работает быстрее. Использование большой модели работает в коде как есть. Так технически это правильный ответ, но изменение всей концепции - гораздо лучший подход.
Спасибо всем за ваши предложения и помощь. Если кто-то заинтересован, я отправлю окончательный результат, как только я буду готов.
ПРИМЕЧАНИЯ: Просто некоторые замечания к некоторым другим ответам: Код, который я пытаюсь запустить, не возникает из-за расширения простых функций/алгоритмов и глупой ненужной разворачивания. Что на самом деле происходит, так это то, что материал, с которого мы начинаем, представляет собой довольно сложные математические объекты и вывод их в числовую вычислимую форму, генерирует эти выражения. Проблема заключается в лежащей в основе физической теории. Сложность промежуточных выражений оценивается факториально, что хорошо известно, но при объединении всего этого материала с чем-то физически измеряемым - наблюдаемым - оно просто сводится к лишь нескольким очень маленьким функциям, которые составляют основу выражений. (В этом отношении определенно "неправильно" с общим и доступным ansatzкоторый называется "теорией возмущений" ). Мы пытаемся довести этот анзац до другого уровня, который уже не является выполнимым аналитически и где база необходимых функций неизвестна. Поэтому мы пытаемся сделать это как можно более грубо. Не лучший способ, но, надеюсь, тот, который помогает в нашем понимании физики в конце концов...
ПОСЛЕДНИЙ РЕДАКТ:
Благодаря всем вашим предложениям мне удалось значительно уменьшить размер кода, используя Mathematica и модификацию генератора кода для func
несколько по строкам верхнего ответа:)
Я упростил функции csc
с Mathematica, доведя ее до 92 Мб. Это неприводимая часть. Первые попытки выполнялись навсегда, но после некоторых оптимизаций это теперь проходит через около 10 минут на одном CPU.
Эффект от func
был драматичным: весь размер кода для них составляет примерно 9 Мб, поэтому код теперь суммируется в диапазоне 100 Мб. Теперь имеет смысл включить оптимизацию, и выполнение выполняется довольно быстро.
Снова, спасибо всем за ваши предложения, я многому научился.