質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

Q&A

解決済

1回答

1868閲覧

fortranのデータについて

tsu_uni

総合スコア17

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

FORTRAN

FORTRAN(フォートラン)は科学時術計算に向いた手続き型プログラミング言語です。 並列計算の最適化が行いやすい特性上、数値予報および気候モデルなどの大規模な計算を行う分野のスーパーコンピュータで使われています。

0グッド

0クリップ

投稿2020/09/29 15:47

編集2020/10/01 01:45

前提・実現したいこと

構造体を要素として持つ大規模な配列において、その構造体に所属する配列の動的割付けを行うことで、メモリの使用量を削減しようと試み下に示すテストプログラムを作成しました。

倍精度実数型を要素としてもつ配列の要素数が12、そしてその配列をもつ構造体配列の要素数が1398101なので、if(mod(i,10))なしでは、メモリ使用量は8byte121398101 = 134.217696MBであると予想をたてました。しかし、実際には291MBとなりました。なおallocateする前ではメモリ使用量は405KBとなっていました。この計算と違う結果になった点がまず一つ目の疑問です。

次にallocateする配列を1/10にしたらメモリ使用量は1/10になるのかと思いましたが、実際には結果は1/10ではなくて194MBとなりました。この1/10にならない理由が2つ目の疑問です。

C言語でも同様のプログラムを書いてみたのですが、今度は14MBと非常に少ないという結果になってしまいました。メモリの使用量というのはそもそもこのように概算することはできないものなのでしょうか?

コンパイラはintel fortran 19.1.1.216を用いています。

該当のソースコード

fortran

1program testff 2 type :: Test 3 real(8),allocatable :: values(:) 4 end type Test 5 6 type(Test),allocatable :: te(:) 7 8 integer :: i 9 integer :: nt = 12 10 integer :: n = 1398101 11 12 allocate(te(n)) 13 14 do i = 1, n 15   !allocate(te(i)%values(nt)) 16 if(mod(i,10)) then 17 allocate(te(i)%values(nt)) 18 te(i)%values = 0.d0 19 end if 20 end do 21 22 call sleep(30) ! メモリの使用量を確認するための時間 23 24end program

c

1#include <stdio.h> 2 3int main(){ 4 struct test { 5 double *value; 6 }; 7 8 int n = 1398101; 9 int nt = 12; 10 int i,j; 11 struct test *te; 12 13 te = malloc(sizeof(struct test) * n); 14 15 for (i=0; i<n; i++){ 16 te[i].value = malloc(sizeof(double) * nt); 17 for (j=0; j<nt; j++){ 18 te[i].value[j] = 0.0; 19 } 20 } 21 22 sleep(30); 23}

追記(2020.10.1): C言語に関しては最適化によって使用してないメモリは削除されてしまっていたようで、最適化をオフにしたら想定通りの結果を得られました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Fortram の場合 storage_size 関数が F2008 位から導入されたので、それで個々の変数や派生型のメモリー上のビットサイズを調べられます。

みたところ te は中の real を allocate する前に 500 ビット超の大きさになっています。

多分、派生型やallocatableの付加情報で、派生型の中に allocate する前から大きなサイズになっているのではないかと思います。

投稿2020/09/29 17:08

curehoney

総合スコア249

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tsu_uni

2020/10/01 01:54 編集

回答いただきありがとうございます。ということはFortranはallocatableなどを含む派生型の配列の要素数を大量にとることは避けた方が良い書き方になるんですね。
curehoney

2020/10/03 11:17

tsu_uni さんの質問にあるように、中身の配列が小さい目の沢山の派生型を確保する場合には、メモリーの無駄が多くなる気がしますね。 Fortran の allocatable は、サイズやランクの付加情報がついており、また自動解放されるのでリークしにくいという特徴(F95以降)もあるので、最終的には損得をはかりにかけてデータ構造をどうとるかバランスをとることになると思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問