Fortran Coder

查看: 17236|回复: 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指向一个大小不同的数组后,内存占用出现了同样的问题,占用了几十倍于指向的数组的大小,请问如何解决?谢谢
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

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

沙发
发表于 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,发现这个结构体一赋内存,内存占用就狂飙

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

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

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

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

5#
发表于 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方便与高效

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

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

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

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

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

7#
发表于 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 点
8#
 楼主| 发表于 2015-12-6 10:08:54 | 只看该作者
pasuka 发表于 2015-12-6 09:37
长度是1800w的话,为啥不考虑上SQL数据库或者Hadoop这类大数据处理平台,再不济的话,也得整个out-of-cor ...

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

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

9#
发表于 2015-12-6 10:11:35 | 只看该作者
从数据库取数,必然比从内存取数会慢很多

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

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

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

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

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

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-23 23:23

Powered by Tencent X3.4

© 2013-2024 Tencent

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