Ошибка компиляции GCC с кодом> 2 ГБ

У меня огромное количество функций, в общей сложности около 2,8 ГБ объектного кода (к сожалению, есть нет пути, научные вычисления ...)

Когда я пытаюсь связать их, я получаю (ожидаемое) перемещение, усеченное для соответствия: 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 & csc, 
             std::vector & 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 & 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 действительно работает намного лучше, производит меньший код и работает быстрее. Использование большой модели работает с кодом как есть. Так что технически это правильный ответ, но изменение всей концепции - гораздо лучший подход.

Спасибо всем за ваши предложения и помощь. Если кому-то интересно, я опубликую окончательный результат, как только буду готов.

ЗАМЕЧАНИЯ: Просто несколько замечаний к другим ответам: код, который я пытаюсь запустить, не связан с расширением простых функций / алгоритмов и глупым ненужным развертыванием. На самом деле происходит то, что мы начинаем с довольно сложных математических объектов, и приведение их к численно вычислимой форме генерирует эти выражения. Проблема на самом деле заключается в основной физической теории. Сложность промежуточных выражений масштабируется факториально, что хорошо известно, но при объединении всего этого материала с чем-то физически измеримым - наблюдаемым - это просто сводится к небольшому количеству очень маленьких функций, которые составляют основу выражений. (В этом отношении определенно есть что-то «неправильное» с общим и единственным доступным анзацем , который называется «теорией возмущений»). Мы пытаемся вывести этот анзац на другой уровень, а именно: аналитически неосуществима, а основа необходимых функций неизвестна. Итак, мы пытаемся использовать его таким образом. Не лучший способ, но, надеюсь, тот, который в конце концов поможет нам понять физику ...

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ: Благодаря всем вашим предложениям мне удалось значительно уменьшить размер кода, используя Mathematica и модификацию генератора кода для функций , что-то вроде строк верхнего ответа :)

I упростили функции csc с помощью Mathematica, снизив его до 92 МБ. Это неприводимая часть. Первые попытки заняли целую вечность, но после некоторых оптимизаций они теперь выполняются примерно за 10 минут на одном процессоре.

Эффект на функции был драматичным: размер всего кода для них уменьшился до примерно 9 МБ, поэтому код теперь составляет 100 МБ. Теперь имеет смысл включить оптимизацию, и выполнение происходит довольно быстро.

Опять же, спасибо всем за ваши предложения, я многому научился.

108
задан Peter Mortensen 30 July 2011 в 14:27
поделиться