• 11771阅读
  • 16回复

[讨论]QT中有没有对大数据处理的合适的内存分配方法 [复制链接]

上一主题 下一主题
离线edwalik
 

只看楼主 倒序阅读 楼主  发表于: 2015-03-25
如题, QT里有没有对大数据处理的比较好的内存分配的方法, 求教高人。


举例来说,就是比如做网格建模,有一个300*300*100的维度的网格模型,每个网格节点用一个体voxel表示,每个voxel有8个角点,这样在内存中,总共用掉的内存就有300*300*100*8*4*3(每个节点用x,y,z表示)=288000000*3字节(274.658M*3),这只是网格节点的定义用掉的内存就有800+M,而且每个网格内还需要存入属性数据,这样内存消耗就更大了,我在QT里试了试,当定义这样一个300*300*100的网格模型时,程序编译通过, 但是运行时自动报错
这个应该是程序运行到一定的节点了,申请内存不足,我知道64位应用就不会出这个问题,但是常用的现在还是32位系统应用,哪位能给出个比较好的32位应用可以解决这个内存消耗的方法呢,在此谢过了。

还想请教跟这个相关的另一个问题,我们自己编写应用的时候,单个exe的线程数QT里是怎么处理的呢,这里的7个线程是QT自己实现的吗。

如果说32位应用的内存申请除了系统的消耗和其他程序的消耗最大能申请2G(实测定义网格时,程序内存达到1.4~1.5G时就自动奔溃了),这个是不是意味着每个线程都可以申请2G的内存?


这个32位软件的内存怎么就能申请到1.7G呢。 真心查不到这类资料, 忘哪位大牛能给些建议
离线timer3309

只看该作者 1楼 发表于: 2015-03-25
1) 可能与你定义数据的结构有关系,导致实际占用的内存超过32位的限制,申请一个1.7G的堆,加上应用占用的其它内存,一般情况下也应该可以用

2)所谓定义的数据是不是一定要在运行时候放在内存中,是值得商榷的,用结构化的二进制文件,利用结构来优化文件的定位和读写,是解决你的问题,并提供更好的系统扩展的方向

3)32位 4G内存 win linux的进程模型,你可以百度。

4)线程数量你在具体应用,进行申请时,数量一般够用。但是如果需要的任务数量少于 CPU的数量*核 的数量,硬件资源等于还有更大的使用空间,申请的任务可以粗浅的理解为能够同时全速执行。而超过了,则需要系统来对多个线程的执行情况进行调度,但肯定是不能同时执行的。

以上 写的很粗浅,希望对你有帮助。
离线edwalik

只看该作者 2楼 发表于: 2015-03-26
由于是行业化的软件输出的网格数据,其二进制文件结构没有具体的结构说明,只有用ASCII文本来解读, 输出的文本数据量太大, 300*300*100的网格文本输出来可能有300M的文本文件,文本文件的结构是有, 但是每一次读写相应的数据区块都要遍历查找关键字,效率太低,所以需要一次录入内存。

请问怎么样可以申请1.7G的堆呢,char a[1700000000]这样的直接申请是不行吧,系统分配不了这么大的内存吧, 我用的是这样或者

有个一问,为什么上面第一个图里的代码运行后程序的内存占用能到1~2个G,而第二个图里的代码运行后程序的内存只占用15M左右呢
离线彩阳

只看该作者 3楼 发表于: 2015-03-26
三维仿真啊,看有没有办法节约内存渲染?
比如说,使用IndexBuffer的形式来保存索引,而用vertexBuffer的形式来保存顶点数据?
另外,是什么格式的模型啊,占用空间有多大?

上面的使用QVector的情况,我觉得可能QVector内部做了一些调整,或者将前面的数据丢失了,所以才没有那么大。
上海Qt开发联盟,热忱地欢迎你的加入!
离线edwalik

只看该作者 4楼 发表于: 2015-03-26
我不做图形啊, 只做数据的处理和计算, 是petrel软件的模型数据, 附件里有一个示例的文本文件, dhmodel.rar (309 K) 下载次数:2

我不清楚你说的怎么保存索引, 我用的办法是所有数据用一维数组的形式加载, 至于每一个网格的空间索引, 通过ijk三个方向的维度去计算出来相应的偏移量, 然后从一维数组里去取数据。

不管怎么说用什么方法来保存顶点数据, 数据量摆在那呢, 维度上了300*300*100之后实际的数据占用的字节数就有800M多, 更别说还有应用程序的一些指针和其他数据还需要一些内存。

我是业余编程的, 没深入理解过实际应用的内存分配问题, 所以请教大牛啦,
离线渡世白玉

只看该作者 5楼 发表于: 2015-03-26
个人思路,用NOSQL 做缓存、、
数据全部存到nosql里、、
按列也好,按行也好、、
然后按照需要的数据实时去查、、、去修改、、



离线edwalik

只看该作者 6楼 发表于: 2015-03-26
回 渡世白玉 的帖子
渡世白玉:个人思路,用NOSQL 做缓存、、
数据全部存到nosql里、、
按列也好,按行也好、、
然后按照需要的数据实时去查、、、去修改、、
....... (2015-03-26 09:50) 

没接触过数据库, 你的意思是要开辟零时的磁盘数据库文件, 做中间存储, 然后随时查找么
离线渡世白玉

只看该作者 7楼 发表于: 2015-03-26
回 edwalik 的帖子
edwalik:没接触过数据库, 你的意思是要开辟零时的磁盘数据库文件, 做中间存储, 然后随时查找么 (2015-03-26 10:09) 

你的数据量,对于一般机器来说,直接放内存不太现实的、、
如果你有分布式内存技术,或者超算级别的、、
或者一个64G内存服务器这么多数据还可能、、
其他你就要考虑其他地方存数据了、、这样对于编程会造成一定麻烦,但是要好好处理又必须啊、、
对于自己写入文件,自己处理查找,自己处理储存结构,我只告诉你这个开发成本太大了、、
我的意思是用现成的nosql做缓存,然后随时增删改查数据、、让其去组织磁盘的存储、、
至于SQL,你没必要,因为表结构设计,还要可变性,你也用不到事务,sql读写效率也比不上nosql、、
个人推荐你去了解下redis和mongodb,看看哪个更符合你的需求、、和你更容易使用、、
一个key-value的,一个文档型的、、
离线渡世白玉

只看该作者 8楼 发表于: 2015-03-26
还有个建议,你这么多数据量,还用32位系统,浪费吗?
是一个进程只允许2G内存,不是线程、、
线程和进程概念不一样的、、
离线pxiao_xiao

只看该作者 9楼 发表于: 2015-03-26
不想用数据库 就自己设计索引 建立内存文件映射
离线edwalik

只看该作者 10楼 发表于: 2015-03-26
回 渡世白玉 的帖子
渡世白玉:还有个建议,你这么多数据量,还用32位系统,浪费吗?
是一个进程只允许2G内存,不是线程、、
线程和进程概念不一样的、、 (2015-03-26 10:20) 

我也想做64位的应用啊, 只是以前一直是用mingw+qt做应用的,都是32位,突然要用64位做应用不知道怎么去编译64位的qt,时间紧任务重,现在只能先用32位的先做个较少维度的网格计算了。

等后面有时间了再考虑考虑怎么用你说的nosql吧, 从来没接触过, 所以不懂。。。
离线edwalik

只看该作者 11楼 发表于: 2015-03-26
回 pxiao_xiao 的帖子
pxiao_xiao:不想用数据库 就自己设计索引 建立内存文件映射 (2015-03-26 11:25) 

不懂怎么搞内存文件映射, 有没有例子呀
离线pxiao_xiao

只看该作者 12楼 发表于: 2015-03-26
就建立以个QFile  用QDataStream写二进制数据(缓存你自己的数据) 结束后 ofile.map(。。。)得到一个unsigned char * 指针 这个指针就是文件的入口 之后怎么操作 就看你的索引是怎么设计的
离线begboy

只看该作者 13楼 发表于: 2015-03-26
回 edwalik 的帖子
edwalik:
由于是行业化的软件输出的网格数据,其二进制文件结构没有具体的结构说明,只有用ASCII文本来解读, 输出的文本数据量太大, 300*300*100的网格文本输出来可能有300M的文本文件,文本文件的结构是有, 但是每一次读写相应的数据区块都要遍历查找关键字,效率太低,所以需要一次录入内存。
请问怎么样可以申请1.7G的堆呢,char a[1700000000]这样的直接申请是不行吧,系统分配不了这么大的内存吧, 我用的是[图片]这样或者[图片]
有个一问,为什么上面第一个图里的代码运行后程序的内存占用能到1~2个G,而第二个图里的代码运行后程序的内存只占用15M左右呢

edwalik,您好!
     1、 第一个图代码采取的是C语言显式申请内存方式,一般用户态下的程序一次性申请内存是有限的,操作
系统会对此有限制。若用户申请超出操作系统设定上限,一般程序会终止运行。
           而第二个图使用的是QT容器,如果您看过QT的实现代码,其实它是在每个容器中的末端预留一定字节
用于扩展和链接用(内容实际是保留链接用的指针),以便QT可以快速插入、删除等使用;
      2、 不知您使用的petrel是2009版还是2012版,对于地质类建模、运算这样的较大数据,我们一般建议
数据处理使用UNIX(LINUX),而处理完数据后再导入Win的petrel。当然如果您能有条件使用国家的超算计算机则另当别论。
      因为UNIX(LINUX)本身设计就为了大规模运算设计,允许一般用户申请远超真实内存的内存需求,系统会自动将
硬盘(外存)作为内存使用,而且运行十分稳定。
      试想下,以前内存才256K,512K时,又如何能运行得了那些大型数据库呢?
      3、 对于文本方式做处理或交换时,要设计好索引的主KEY和辅KEY,采用哈希等方式是可以快速索引和运算的。
       40多G的文本文件在2G内存的UNIX普通PC机一次性处理是没有任何压力的。这点请您放心。
祝好运!
begboy

离线roywillow

只看该作者 14楼 发表于: 2015-03-26
回 edwalik 的帖子
edwalik:我也想做64位的应用啊, 只是以前一直是用mingw+qt做应用的,都是32位,突然要用64位做应用不知道怎么去编译64位的qt,时间紧任务重,现在只能先用32位的先做个较少维度的网格计算了。
等后面有时间了再考虑考虑怎么用你说的nosql吧, 从来没接触过, 所以不懂。。。 (2015-03-26 11:33) 

qt官方提供了64位版的sdk,除非你一定要用自己的编译器,一般用官方那套就可以了吧
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线edwalik

只看该作者 15楼 发表于: 2015-03-30
回 begboy 的帖子
begboy:edwalik,您好!
     1、 第一个图代码采取的是C语言显式申请内存方式,一般用户态下的程序一次性申请内存是有限的,操作
系统会对此有限制。若用户申请超出操作系统设定上限,一般程序会终止运行。
          .. (2015-03-26 15:54) 

LINUX下我还没有试验过, 回头可以试试看。

QT容器类的实现代码我没有细看, 我本身不是做代码和程序的, 只是零时接了个做软件的活, 本来想着就当一个简单应用来做了, 没想到细做起来, 里面涉及到的内容还不少

多谢指点
离线edwalik

只看该作者 16楼 发表于: 2015-03-30
回 roywillow 的帖子
roywillow:qt官方提供了64位版的sdk,除非你一定要用自己的编译器,一般用官方那套就可以了吧 (2015-03-26 22:39) 

我一直用的5.x之前的4.x版本, 在官方没找到64的呢。。
快速回复
限100 字节
 
上一个 下一个