各プロセスの使用リソースが記載されている/proc/self/statusの中のメモリに関する部分をジョブ実行中に参照・出力できます。
- VmRSS: 実メモリ使用サイズ
- VmHWM: 実メモリ使用サイズのピーク
- VmSize: 現在の仮想メモリ使用サイズ
- VmPeak: VmSizeのピーク値
ここでは物理メモリに確保されたメモリ量が知りたいので,VmRSSとVmHWMを出力します。
以下にC言語とFortranでの例を示します。この関数をソースコードの適切な場所に挿入すると,メモリ使用量を出力できます。
- C言語での関数例
- Fortranでのサブルーチン例
- 出力例
格子数512^3のメッシュ法を使用し,64並列(1ノード)で計算した出力を以下に示します。上記のプログラム例の出力に加えて,プロセス番号も同時に出力しています。
myrank = 0, VmHWM: 1137604 kB, VmRSS: 1137604 kB myrank = 1, VmHWM: 1136848 kB, VmRSS: 1136848 kB .... myrank = 63, VmHWM: 1137160 kB, VmRSS: 1137160 kB
この出力結果を見ると,各プロセスが使用するVmHWMはおおよそ1140 MBで一定であることが確認できます。この計算に必要なメモリ量は全プロセスの値を合計して約73 GBとなります。一方,システムMの1ノードに搭載されたメモリは128GBですので,同じ解像度での計算はシステムM1ノードで実行可能です。
格子幅を半分にする場合は,メモリ使用量がおおよそ2^3倍(約580GB)となり,システムMの1ノードでは計算を実行できなくなります。その場合は以下の選択肢をご検討ください。
- システムMを8ノード利用する(1ノード当たり64並列の場合。カテゴリAへの申請が必要)。
- システムPを2ノード利用する(1ノード当たり64並列の場合)。
#include <stdlib.h> #include <stdio.h> #include <string.h> void print_mem() { char line[1000]; FILE *in_fh; in_fh = fopen("/proc/self/status","r"); int vmhwm, vmrss; while (fgets(line, sizeof(line), in_fh)) { if (strncmp(line, "VmHWM:", 6) == 0) { sscanf(line, "VmHWM: %d kB", &vmhwm); } else if (strncmp(line, "VmRSS:", 6) == 0) { sscanf(line, "VmRSS: %d kB", &vmrss); } } printf("VmHWM: %d kB, VmRSS: %d kB\n",vmhwm,vmrss); }
subroutine print_mem parameter(lun=99) character*80 line integer(kind=8) hwm,rss open(lun,file='/proc/self/status') do while(.true.) read(lun,'(a)',end=99) line if(line(1:6).eq.'VmHWM:') read(line(8:80),*) hwm if(line(1:6).eq.'VmRSS:') read(line(8:80),*) rss enddo 99 close(lun) print *,'VmHWM: ',hwm,'kB, ','VmRSS: ',rss,'kB' return end