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