私は合計で約2.8 GBのオブジェクトコードの膨大な数の関数を持っています(残念ながら、回避策はありません。科学計算...)
それらをリンクしようとすると、(予期される)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 MB)を持っています。
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
は比較的小さくti
、外部ライブラリからdoubleを返すだけで、必要な定数x14、x15、...、ds0、...などを保持します。ご覧のとおり、csc[]
は事前に計算された値のマップであり、次の形式の個別のオブジェクトファイル(これも数百のサイズでそれぞれ約1 MBです)でも評価されます。
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)の式を簡略化することで、定義のコードサイズを約1分の1 に減らすことができました。私はまた、コードを生成する前に他のいくつかのトリックを適用することでこれをさらに桁違いに減らすいくつかの方法(これにより、この部分が約100 MBになる)を見つけ、このアイデアが機能することを願っています。
さてあなたの答えに関連して:私はループをfunc
sで再びロールバックしようとしています、そこでCASはあまり役に立ちませんが、私はすでにいくつかのアイデアを持っています。たとえば、式をのような変数で並べ替え、Python x12, x13,...
でを解析し、csc
それらを相互に関連付けるテーブルを生成します。その後、少なくともこれらのパーツをループとして生成できます。これが今のところ最良の解決策であると思われるので、これを最良の回答としてマークします。
ただし、VJoの功績も認めたいと思います。GCC 4.6は実際、はるかにうまく機能し、より小さなコードを生成し、より高速です。大きなモデルを使用すると、コードでそのまま動作します。技術的にはこれが正しい答えですが、コンセプト全体を変更する方がはるかに優れたアプローチです。
皆さんの提案と助けに感謝します。誰か興味があれば、準備ができ次第、最終結果を投稿します。
備考:他のいくつかの回答へのほんの一部の備考:私が実行しようとしているコードは、単純な関数/アルゴリズムの展開と愚かな不必要な展開に由来していません。実際に何が起こるかというと、私たちが始めるのはかなり複雑な数学的オブジェクトであり、それらを数値計算可能な形式にすると、これらの式が生成されます。問題は実際には基礎となる物理理論にあります。中間式の複雑さは、よく知られていますが、これらすべてを物理的に測定可能なもの(観測可能)に組み合わせると、式の基礎を形成するごく一部の非常に小さな関数に要約されます。(「間違った」何かが一般的で、この点で間違いがあるのみ利用可能「摂動論」と呼ばれるansatz)このansatzを別のレベルにしようとします。これは、分析的にはもはや実行できず、必要な関数の基礎が不明です。したがって、このようにブルートフォースにしようとします。最善の方法ではありませんが、うまくいけば、最終的に手元にある物理学の理解に役立つ方法です...
最終編集:
すべての提案のおかげで、Mathematicaとfunc
上位の回答の行に沿ってsのコードジェネレータの変更を使用して、コードサイズを大幅に縮小することができました:)
csc
Mathematicaで関数を簡略化し、92 MBまで下げました。これは還元不可能な部分です。最初の試行は永遠にかかりましたが、いくつかの最適化の後、これは単一のCPUで約10分で実行されます。
func
sへの影響は劇的でした:それらの全体のコードサイズは約9 MBに減少しているため、コードは合計で100 MBの範囲になります。最適化をオンにすることは理にかなっており、実行は非常に高速です。
繰り返しますが、皆さんの提案に感謝します。私はたくさん学びました。
mmap
、実行時に外部バイナリから自分で移動する必要があります。