合計で約2.8GBのオブジェクトコードを含む膨大な数の関数があります(残念ながら、科学計算を回避する方法はありません...)
それらをリンクしようとすると、(予期される)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
は比較的小さく、必要な定数x14、x15、...、ds0、...などを保持ti
しますが、外部ライブラリからdoubleを返すだけです。ご覧のとおり、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などの新しいセットが選択されて次の値が生成されます。そして、これは105から106回行わなければなりません...
EDIT3:
これまでの提案と議論に感謝します...正直なところ、これを正確に行う方法がわからないので、コード生成時にループをロールアップしようとしますが、これが最善の策です。
ところで、私は「これは科学計算であり、最適化する方法はありません」の背後に隠れようとはしませんでした。
このコードの基礎は、私が実際にアクセスできない「ブラックボックス」から出てきたものであり、さらに、単純な例ですべてがうまく機能し、主に実際に起こっていることに圧倒されていると感じていますワールドアプリケーション...
EDIT4:
csc
そこで、数式処理システム(Mathematica )で式を簡略化することで、定義のコードサイズを約4分の1に減らすことができました。コードを生成する前に他のトリックを適用することで(この部分を約100 MBに減らす)、もう1桁程度減らす方法もわかりました。このアイデアが機能することを願っています。
今あなたの答えに関連しています:
func
CASがあまり役に立たないsでループを再びロールバックしようとしていますが、すでにいくつかのアイデアがあります。たとえば、のような変数で式を並べ替え、 Pythonでsをx12, x13,...
解析し、csc
それらを相互に関連付けるテーブルを生成します。そうすれば、少なくともこれらの部分をループとして生成できます。これがこれまでのところ最良の解決策であるように思われるので、私はこれを最良の答えとしてマークします。
ただし、VJoの功績も認めたいと思います。GCC 4.6は確かにはるかにうまく機能し、より小さなコードを生成し、より高速です。大きなモデルを使用すると、コードをそのまま使用できます。したがって、技術的にはこれが正解ですが、概念全体を変更する方がはるかに優れたアプローチです。
あなたの提案と助けをありがとうございました。興味のある方は、準備ができ次第最終結果を掲載します。
備考:
他のいくつかの答えに対するいくつかの注意:私が実行しようとしているコードは、単純な関数/アルゴリズムの拡張と愚かな不必要な展開に由来するものではありません。実際に起こることは、私たちが始めたものはかなり複雑な数学的オブジェクトであり、それらを数値的に計算可能な形式にすることでこれらの式が生成されるということです。問題は、実際には基礎となる物理理論にあります。中間式の複雑さは階乗的にスケーリングしますが、これはよく知られていますが、これらすべてを物理的に測定可能なもの(観察可能なもの)に組み合わせると、式の基礎を形成する非常に小さな関数のほんの一握りに要約されます。(この点に関しては、一般的で唯一利用可能な仮説に関しては間違いなく「間違った」ものがありますこれは「摂動論」と呼ばれます)私たちは、この仮説を別のレベルに引き上げようとします。これは、もはや分析的に実行可能ではなく、必要な関数の基礎がわからない場合です。ですから、このようにブルートフォースを試みます。最善の方法ではありませんが、うまくいけば、最終的に手元にある物理学の理解に役立つ方法です...
最終編集:
すべての提案のおかげで、Mathematicaを使用しfunc
、トップアンサーの線に沿ってsのコードジェネレーターを変更することで、コードサイズを大幅に削減することができました:)
Mathematicaで関数を単純化し、csc
92MBに減らしました。これは既約部分です。最初の試みは永遠にかかりましたが、いくつかの最適化の後、これは現在、単一のCPUで約10分で実行されます。
sへの影響func
は劇的でした。それらのコード全体のサイズは約9MBに減少したため、コードの合計は100MBの範囲になりました。これで、最適化をオンにするのが理にかなっており、実行は非常に高速です。
繰り返しになりますが、皆さんの提案に感謝します。私はたくさんのことを学びました。