各プロセスの使用リソースが記載されている/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