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