Fortran Coder

查看: 928|回复: 11

[编译器] 自定义类型的内存占用巨大

[复制链接]

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
发表于 2015-12-5 18:53:18 | 显示全部楼层 |阅读模式
想要定义一个数据类型,希望能中间包含一个可变大小的数组,写了代码如下
[Fortran] 纯文本查看 复制代码
type cell
integer :: fn
integer, dimension(:), allocatable ::nd
end type cell
type(cell), dimension(:), allocatable ::elem
allocate(elem(10000))

只是给结构体elem赋了内存,维数10000,没有给nd赋内存,但是在进程管理器里查看已经占用了几十倍于10000*4字节的内存,而且再给nd赋内存并赋值后,内存进一步增加。
原以为自定义结构体中不能包含可变大小的数组,于是修改代码为:
[Fortran] 纯文本查看 复制代码
type cell
integer :: fn
integer, dimension(:), pointer ::nd
end type cell
type(cell), dimension(:), allocatable ::elem
allocate(elem(10000))

这样给结构体elem赋内存后,内存占用无异常,但当每一个指针elem(i)%nd指向一个大小不同的数组后,内存占用出现了同样的问题,占用了几十倍于指向的数组的大小,请问如何解决?谢谢
回复

使用道具 举报

443

帖子

2

主题

0

精华

大宗师

F 币
2977 元
贡献
1772 点

水王勋章元老勋章热心勋章

发表于 2015-12-5 18:58:57 | 显示全部楼层
完整的代码?
操作系统?
编译器?
编译参数?
啥也没有的话,就算盖茨也没辙

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
 楼主| 发表于 2015-12-5 19:43:39 | 显示全部楼层
本帖最后由 jovan 于 2015-12-5 19:45 编辑

操作系统是:Win7编译器:Intel Visual Studio2010
编译环境:x64 Release
完整代码太长了,没法贴,我在一些可疑的地方赋内存之后pause,发现这个结构体一赋内存,内存占用就狂飙

1237

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
790 元
贡献
357 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2015-12-5 20:24:00 | 显示全部楼层
楼主的问题已在QQ群讨论解决:
1.楼主使用的64位编译器,一个地址占8字节,而非楼主计算的4字节
2.由于Fortran的可分配数组(指针同),除了记录数组的首地址(8字节)之外,还记录数组的维度,每个维度的上限 / 下限 / 间距。因此,这些结构(或称数组描述符 descriptor ) 占用约32字节

443

帖子

2

主题

0

精华

大宗师

F 币
2977 元
贡献
1772 点

水王勋章元老勋章热心勋章

发表于 2015-12-5 20:44:45 | 显示全部楼层
fcode 发表于 2015-12-5 20:24
楼主的问题已在QQ群讨论解决:
1.楼主使用的64位编译器,一个地址占8字节,而非楼主计算的4字节
2.由于Fort ...

既然如此,还不如在C里面定义这个结构体及其相关操作,然后ISO C BINDING做个interface
有些譬如链表、哈希表啥的,Fortran真的不如C方便与高效

1237

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
790 元
贡献
357 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2015-12-5 22:59:17 | 显示全部楼层
如果把变量和结构都写入 C 定义,那么相关的计算也必须写入 C,因为可分配数组和fortran指针,都是特殊的数据结构。
fortran的指针包含更丰富的内容,以至于它更安全,不容易越界或指向数组之外。当然,它是以牺牲内存为代价的。
通常来说,较大的数组,但数组个数不多,那么牺牲一点内存来存储这些额外的信息(维度/上下限)是值得的。

像楼主这种1800万个可分配数组,毕竟是较少的情况。

443

帖子

2

主题

0

精华

大宗师

F 币
2977 元
贡献
1772 点

水王勋章元老勋章热心勋章

发表于 2015-12-6 09:37:21 | 显示全部楼层
fcode 发表于 2015-12-5 22:59
如果把变量和结构都写入 C 定义,那么相关的计算也必须写入 C,因为可分配数组和fortran指针,都是特殊的数 ...

长度是1800w的话,为啥不考虑上SQL数据库或者Hadoop这类大数据处理平台,再不济的话,也得整个out-of-core的模式
直接囫囵吞枣往计算机内存塞那么多信息,实在是费力不讨好的,譬如高清视频动辄20、30G,远超过内存容量,但是播放的时候,只会读入一段数据
lz应该去看看数据库以及大数据处理相关的现成软件包或框架

7

帖子

2

主题

0

精华

入门

F 币
33 元
贡献
19 点
 楼主| 发表于 2015-12-6 10:08:54 | 显示全部楼层
pasuka 发表于 2015-12-6 09:37
长度是1800w的话,为啥不考虑上SQL数据库或者Hadoop这类大数据处理平台,再不济的话,也得整个out-of-cor ...

这个是流体计算网格的前处理程序,以前处理小网格没有啥问题,现在算大网格出了这问题,回头我换个平台试试看,要还是不行就考虑改程序,数据库完全不懂...

1237

帖子

12

主题

5

精华

论坛跑堂

Fcode跑堂伙计

F 币
790 元
贡献
357 点

新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2015-12-6 10:11:35 | 显示全部楼层
从数据库取数,必然比从内存取数会慢很多

时间(执行效率)和空间(内存大小)总是不可兼得,两难相权取其轻吧。

443

帖子

2

主题

0

精华

大宗师

F 币
2977 元
贡献
1772 点

水王勋章元老勋章热心勋章

发表于 2015-12-6 10:14:46 | 显示全部楼层
jovan 发表于 2015-12-6 10:08
这个是流体计算网格的前处理程序,以前处理小网格没有啥问题,现在算大网格出了这问题,回头我换个平台试 ...

CFD计算的话,不妨去OpenFoam的论坛或者mailing-list去问问看,肯定有成熟的解决办法
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

QQ|捐赠本站|Archiver|关于我们 About Us|群聊|Fcode

GMT+8, 2018-7-23 08:26

Powered by Discuz! X3.2

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表