doridoridoriand’s diary

主に技術的なことを書いていく予定(たぶん)

2GBを超えるメモリを1つのプロセスで確保したい場合

C++で大量の変数を使って計算したい時に、たくさん変数確保するようなことがあるかと思います。 例えば以下のようなコードとか

const int REPEAT_TIMES = 10000;
double num_a[REPEAT_TIMES][REPEAT_TIMES], num_b[REPEAT_TIMES][REPEAT_TIMES], num_c[REPEAT_TIMES][REPEAT_TIMES];
double num_d[REPEAT_TIMES][REPEAT_TIMES], num_e[REPEAT_TIMES][REPEAT_TIMES], num_f[REPEAT_TIMES][REPEAT_TIMES];
double num_g[REPEAT_TIMES][REPEAT_TIMES], num_h[REPEAT_TIMES][REPEAT_TIMES], num_i[REPEAT_TIMES][REPEAT_TIMES];
double num_j[REPEAT_TIMES][REPEAT_TIMES], num_k[REPEAT_TIMES][REPEAT_TIMES], num_l[REPEAT_TIMES][REPEAT_TIMES];
double num_m[REPEAT_TIMES][REPEAT_TIMES], num_n[REPEAT_TIMES][REPEAT_TIMES], num_o[REPEAT_TIMES][REPEAT_TIMES];
double num_p[REPEAT_TIMES][REPEAT_TIMES], num_q[REPEAT_TIMES][REPEAT_TIMES], num_r[REPEAT_TIMES][REPEAT_TIMES];

まあウンコードなのは気にしないでくださいw
しかしこのようなコードを書いて、いざコンパイルしようとした時次のようなエラーが出てくることがあります

/tmp/ccEo3zaI.o: In function `_Z11calc_vectorv.omp_fn.2':
calcMultiThreadManyDataDouble.cpp:(.text+0x3ba): relocation truncated to fit: R_X86_64_32S against symbol `num_d' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x3e7): relocation truncated to fit: R_X86_64_32S against symbol `num_e' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x414): relocation truncated to fit: R_X86_64_32S against symbol `num_f' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x441): relocation truncated to fit: R_X86_64_32S against symbol `num_g' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x46e): relocation truncated to fit: R_X86_64_32S against symbol `num_h' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x49b): relocation truncated to fit: R_X86_64_32S against symbol `num_i' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x4c8): relocation truncated to fit: R_X86_64_32S against symbol `num_j' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x4f5): relocation truncated to fit: R_X86_64_32S against symbol `num_k' defined in .bss section in /tmp/ccEo3zaI.o
calcMultiThreadManyDataDouble.cpp:(.text+0x522): additional relocation overflows omitted from the output
collect2: ld returned 1 exit status

relocation truncated to fit

再配置はサイズに合うように切り捨てられました??ん??どういうことだ?

色々調べていたら次のサイトに巡りあうことが出来ました

シングルプロセッサプログラムの最適化

つまるところ、64ビットコンパイラでは、デフォルトでは32ビットと互換性を保つために2GB制限をかけているけど、コンパイルオプションを追加してやることで64ビットアプリケーションとしてコンパイル出来るようになるようです

よってコンパイル時に

$ g++ ファイル名.cpp -o 出力したい名前 -mcmodel=large

としてやればコンパイル出来るようになります。
実行結果を見てみると

この計算機はメモリが24GB積んであるのでこのプロセスだけで13.7GB程度消費しています。 …やばいな笑