2017-05-20 9 views
0

私はいくつかの行列計算を行うために固有ライブラリを使用していました。私は長い行列を定義しなければなりません(実際にはそれほど大きくなく、ちょうど300x300)、各要素は長い複雑な指数表現で構成されています。 C++:-O2最適化で膨大な量の式のコンパイルに失敗しましたか?

は私が何を意味するかの印象を与えるために、私は窓にmingwの-W64を使用しています

#include <iostream> 
#include <complex> 
#include <Eigen/Dense> 
using namespace Eigen; 

int main() 
{ 
typedef std::complex<double> cd; 
MatrixXcd h(300,300); 
double kx,ky; 
kx=1.; 
ky=1.; 
h.setZero(300,300); 
h(0,0)=cd(6.942755,0.) + 0.043986/exp(cd(0,1)*(0. - 2.0238820899708214*kx - 7.55323078829979*ky)) - 0.010802/exp(cd(0,1)*(0. + 5.529348698328969*kx - 5.529348698328969*ky)) + 0.043986/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)) + 0.043986/exp(cd(0,1)*(0. + 7.55323078829979*kx + 2.0238820899708214*ky)) - 0.010802/exp(cd(0,1)*(0. - 5.529348698328969*kx + 5.529348698328969*ky)) + 0.043986/exp(cd(0,1)*(0. + 2.0238820899708214*kx + 7.55323078829979*ky)); 
h(0,2)=cd(0.,0.) + 0.095916/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)) - 0.131689/exp(cd(0,1)*(0. + 7.55323078829979*kx + 2.0238820899708214*ky)); 
h(0,3)=cd(-0.10825,0.) - 0.011519/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)); 
... 
...//6000 more lines omitted here 
} 

私の行列定義のごく一部をコピーし、コンパイラは罰金を設定しました。しかし、上記のコードを

g++ -O2 code.cpp 

とコンパイルすると、コンパイルはポップアップダイアログで失敗します!

enter image description here

と私は慎重に、タスクマネージャを見れば、コンパイルは約1GBのメモリ使用量で停止。

しかし、-O0オプションを使用してコードを再度コンパイルすると、すべての最適化が無効になります。メモリ使用量が2GBに近いピークに達しても、コンパイルは成功しました。 エラーはメモリが原因ではありません。

さらに、この動作は、Eigenライブラリとは関係がないことを確認できます。私はEigenを使用し、同じ変数に代入すべてを置き換える、この

#include <iostream> 
#include <complex> 

int main() 
{ 
typedef std::complex<double> cd; 
cd tmp; 
double kx,ky; 
kx=1.; 
ky=1.; 
tmp=cd(6.942755,0.) + 0.043986/exp(cd(0,1)*(0. - 2.0238820899708214*kx - 7.55323078829979*ky)) - 0.010802/exp(cd(0,1)*(0. + 5.529348698328969*kx - 5.529348698328969*ky)) + 0.043986/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)) + 0.043986/exp(cd(0,1)*(0. + 7.55323078829979*kx + 2.0238820899708214*ky)) - 0.010802/exp(cd(0,1)*(0. - 5.529348698328969*kx + 5.529348698328969*ky)) + 0.043986/exp(cd(0,1)*(0. + 2.0238820899708214*kx + 7.55323078829979*ky)); 
tmp=cd(0.,0.) + 0.095916/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)) - 0.131689/exp(cd(0,1)*(0. + 7.55323078829979*kx + 2.0238820899708214*ky)); 
tmp=cd(-0.10825,0.) - 0.011519/exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky)); 
... //6000 more lines omitted 
} 

のようにコンパイルも-O2オプションのために失敗していない場合でも

また、問題はmingwコンパイラに限定されません。私はまた、インテルの並列スタジオicl.exeを試しました。状況はさらに悪く、コンパイルには30分以上かかり、それが繰り返し行われているように見えますが、私はそれが完了するのを待つ忍耐がなく、おそらく最後にも失敗する可能性があります。

だから私の質問は、-O2でコンパイルに失敗した原因ですか? -O2のコードを作成するにはどうすればいいですか?また、多くの表現があるにもかかわらず、それらは単純に要素expで構成されているので、なぜコンパイルに時間とメモリがかかるのですか?コンパイルを高速化するためのトリックですか?

更新

マルク・Glisseの提案によると、私は次のことを実行します。 -O1が動作しますが、コードが科学計算目的のため、少なくともO2は必要です。スピードは重要です。

R:\>g++ -O1 -ftime-report eigen.cpp 

Execution times (seconds) 
phase setup    : 0.01 (0%) usr 1540 kB (0%) ggc 
phase parsing   : 6.06 (5%) usr 412774 kB (25%) ggc 
phase lang. deferred : 0.18 (0%) usr 6491 kB (0%) ggc 
phase opt and generate : 122.65 (95%) usr 1203926 kB (74%) ggc 
|name lookup   : 0.61 (0%) usr 39968 kB (2%) ggc 
|overload resolution : 2.18 (2%) usr 151685 kB (9%) ggc 
garbage collection  : 1.48 (1%) usr  0 kB (0%) ggc 
callgraph construction : 0.65 (1%) usr 28545 kB (2%) ggc 
callgraph optimization : 0.41 (0%) usr  6 kB (0%) ggc 
ipa dead code removal : 0.02 (0%) usr  0 kB (0%) ggc 
ipa inlining heuristics : 0.58 (0%) usr 6172 kB (0%) ggc 
ipa reference   : 0.02 (0%) usr  0 kB (0%) ggc 
ipa profile    : 0.11 (0%) usr  0 kB (0%) ggc 
ipa pure const   : 0.20 (0%) usr  0 kB (0%) ggc 
cfg cleanup    : 0.04 (0%) usr  0 kB (0%) ggc 
trivially dead code  : 0.05 (0%) usr  0 kB (0%) ggc 
df scan insns   : 0.09 (0%) usr  0 kB (0%) ggc 
df multiple defs  : 0.03 (0%) usr  0 kB (0%) ggc 
df live regs   : 0.13 (0%) usr  0 kB (0%) ggc 
df live&initialized regs: 0.04 (0%) usr  0 kB (0%) ggc 
df reg dead/unused notes: 0.17 (0%) usr 2440 kB (0%) ggc 
register information : 0.01 (0%) usr  0 kB (0%) ggc 
alias analysis   : 0.05 (0%) usr 1546 kB (0%) ggc 
alias stmt walking  : 27.43 (21%) usr 19006 kB (1%) ggc 
rebuild jump labels  : 0.03 (0%) usr  0 kB (0%) ggc 
preprocessing   : 0.63 (0%) usr 8732 kB (1%) ggc 
parser (global)   : 0.30 (0%) usr 80513 kB (5%) ggc 
parser struct body  : 0.36 (0%) usr 20184 kB (1%) ggc 
parser enumerator list : 0.03 (0%) usr 1004 kB (0%) ggc 
parser function body : 3.52 (3%) usr 253532 kB (16%) ggc 
parser inl. func. body : 0.16 (0%) usr 6243 kB (0%) ggc 
parser inl. meth. body : 0.24 (0%) usr 12261 kB (1%) ggc 
template instantiation : 0.75 (1%) usr 36791 kB (2%) ggc 
early inlining heuristics: 0.74 (1%) usr 78738 kB (5%) ggc 
inline parameters  : 0.60 (0%) usr 3273 kB (0%) ggc 
integration    : 34.96 (27%) usr 421223 kB (26%) ggc 
tree gimplify   : 0.93 (1%) usr 78917 kB (5%) ggc 
tree eh     : 1.81 (1%) usr 147729 kB (9%) ggc 
tree CFG construction : 0.26 (0%) usr 47487 kB (3%) ggc 
tree CFG cleanup  : 0.92 (1%) usr  0 kB (0%) ggc 
tree copy propagation : 0.03 (0%) usr  0 kB (0%) ggc 
tree PTA    : 1.80 (1%) usr  167 kB (0%) ggc 
tree PHI insertion  : 0.07 (0%) usr  519 kB (0%) ggc 
tree SSA rewrite  : 1.63 (1%) usr 97983 kB (6%) ggc 
tree SSA other   : 0.13 (0%) usr  17 kB (0%) ggc 
tree SSA incremental : 28.75 (22%) usr  5 kB (0%) ggc 
tree operand scan  : 2.13 (2%) usr 65917 kB (4%) ggc 
dominator optimization : 0.08 (0%) usr 2043 kB (0%) ggc 
tree SRA    : 2.65 (2%) usr 56210 kB (3%) ggc 
tree CCP    : 2.42 (2%) usr 37765 kB (2%) ggc 
tree split crit edges : 0.11 (0%) usr 2953 kB (0%) ggc 
tree reassociation  : 0.04 (0%) usr  0 kB (0%) ggc 
tree FRE    : 3.35 (3%) usr 35524 kB (2%) ggc 
tree code sinking  : 0.01 (0%) usr  0 kB (0%) ggc 
tree linearize phis  : 0.01 (0%) usr  6 kB (0%) ggc 
tree backward propagate : 0.02 (0%) usr  0 kB (0%) ggc 
tree forward propagate : 0.38 (0%) usr  8 kB (0%) ggc 
tree conservative DCE : 0.13 (0%) usr  1 kB (0%) ggc 
tree aggressive DCE  : 0.33 (0%) usr  2 kB (0%) ggc 
tree DSE    : 0.45 (0%) usr  4 kB (0%) ggc 
tree SSA uncprop  : 0.01 (0%) usr  0 kB (0%) ggc 
dominance frontiers  : 0.06 (0%) usr  0 kB (0%) ggc 
dominance computation : 0.65 (1%) usr  0 kB (0%) ggc 
out of ssa    : 0.09 (0%) usr  1 kB (0%) ggc 
expand vars    : 0.02 (0%) usr  765 kB (0%) ggc 
expand     : 0.13 (0%) usr 13796 kB (1%) ggc 
post expand cleanups : 0.03 (0%) usr 2868 kB (0%) ggc 
forward prop   : 0.08 (0%) usr  156 kB (0%) ggc 
CSE      : 0.08 (0%) usr  304 kB (0%) ggc 
dead code elimination : 0.03 (0%) usr  0 kB (0%) ggc 
dead store elim1  : 0.09 (0%) usr  763 kB (0%) ggc 
dead store elim2  : 0.08 (0%) usr  613 kB (0%) ggc 
loop init    : 0.15 (0%) usr  65 kB (0%) ggc 
branch prediction  : 0.12 (0%) usr  19 kB (0%) ggc 
combiner    : 0.10 (0%) usr  216 kB (0%) ggc 
if-conversion   : 0.01 (0%) usr  0 kB (0%) ggc 
integrated RA   : 0.43 (0%) usr 9659 kB (1%) ggc 
LRA non-specific  : 0.26 (0%) usr  305 kB (0%) ggc 
LRA virtuals elimination: 0.03 (0%) usr  304 kB (0%) ggc 
LRA create live ranges : 0.03 (0%) usr  152 kB (0%) ggc 
LRA hard reg assignment : 0.02 (0%) usr  0 kB (0%) ggc 
reload CSE regs   : 0.19 (0%) usr  916 kB (0%) ggc 
thread pro- & epilogue : 0.04 (0%) usr  14 kB (0%) ggc 
hard reg cprop   : 0.07 (0%) usr  0 kB (0%) ggc 
shorten branches  : 0.08 (0%) usr  0 kB (0%) ggc 
final     : 0.16 (0%) usr  279 kB (0%) ggc 
initialize rtl   : 0.01 (0%) usr  12 kB (0%) ggc 
rest of compilation  : 0.31 (0%) usr  879 kB (0%) ggc 
remove unused locals : 2.24 (2%) usr  0 kB (0%) ggc 
address taken   : 1.00 (1%) usr 37564 kB (2%) ggc 
rebuild frequencies  : 0.02 (0%) usr  0 kB (0%) ggc 
TOTAL     : 128.90   1624743 kB 
+0

中間のサイズの例を-ftime-reportでコンパイルして、何時間がかかるかを調べることができます。しかし、大規模な自動生成ソースファイル(-O1を試したかどうかは言及していません)では、-O1に固執することが推奨されます。 –

+0

こんにちは、@MarcGlisseご意見ありがとうございます。私は自分の投稿を更新しました。 '-O1'は動作しますが、' -O2'が必要です – user15964

答えて

0

I用語のような表現の一部の冗長性を参照して:H(0,2)およびH(0,3)に見

exp(cd(0,1)*(0. - 7.55323078829979*kx - 2.0238820899708214*ky))

-O2は、コンパイルにパターンの検出と再利用を強制します。複雑さは6k行の表現では高すぎるようです。 tmp変数でgccを助けることができます。依存グラフを作成してからコードを生成するのと同じです。

+0

こんにちは、norisknofun。答えてくれてありがとう。繰り返されるパターンは長いコンパイル時間を説明することができますが、コンパイルが失敗してはならないと思います。何が失敗の原因ですか? – user15964

関連する問題