中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 8086 上的多任务 GUI 开发 问题集, 欢迎赐教!
« [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] »
作者:
标题: 8086 上的多任务 GUI 开发 问题集, 欢迎赐教! 上一主题 | 下一主题
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 46 楼』:  



  Quote:
Originally posted by jawbin at 2006-5-27 13:38:
我某些时候(例如,可能等同于 MS 的 GDI 堆的部分可能就会这样,此前我的时钟就是类似这样的,总之一些系统堆可能会这样处理以提高可能微乎其微 ...

jawbin 兄很喜欢跟 MS 的 GDI 接口较劲啊,呵呵。其实打开 DC 的时候只不过是打开了一个句柄,实际的开销不过是 "++reference_count;" 之类的引用计数操作,通常没有什么内存分配的问题。

在栈中分配对象的大小跟最终生成的可执行程序尺寸没有任何关系。绝大部分编译器中,在栈中分配对象仅仅是修改一下相对于 ESP 的一个偏移值而已。不信的话你可以编译以下C代码:

int main(int argc, char* argv[])
{
    unsigned char gbTEST[64*1024*1024];  // 在栈上分配64MB缓冲区
    return 0;
}

看看编译出来的可执行程序会不会有64MB那么大。甚至,不光这个可执行程序会很小,运行时所消耗的内存甚至也不会超过几K,因为gbTEST只是在地址空间上保留了64MB的段落,由于没有真正的使用到它,所以分配给你的仅仅是进程虚地址空间中的一段而不是物理内存。

2006-5-27 16:37
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 47 楼』:  

被 asbai 兄看穿了, 我是很看不惯 GDI
不过依据 MS 的说法, 它加速 DC 访问是用了 5 个 common DCs 中的一个用来缓存最近使用的 DC,而当这 5

个 DCs 不够的时候,就需要增加更多的 DCs 了. 至于别的小对象(笔,刷子等), 还不清楚, 可能也类似, 但是

问题应该与此相比小很多, 可以先不考虑. 当然 CS_OWNDC 也可以使窗体拥有自己的 DC, 但是, Windows 5.x

之前不被提倡, 估计是 Windows 5.x 之后系统本身对硬件资源的要求就高了, 所以可以"奢侈"一些了,无论如

何, DC 这个稍微有点庞大的东西总不能在资源紧张的系统上原样照搬. 每个窗体的 DC 的内容应该是不同的,

所以不可能引用吧. 即使如果某一个固定的窗口的 DC "相同", 也只需要获取一次(在窗体刚创建之后),最后销

毁一次, 不需要在频繁调用的 OnPaint 中开始来个 ++reference_count, 末尾来个 --reference_count 这样

的假动作吧?. 无论如何, 即使我不去"善意地"猜测它怎么在内部优化实现, 我还是对这样的代码很不舒服.

另外, asbai 兄的举例的确指出了我的错误, 应该是我疏忽了, 我指的是需要初始化的数据(由于使用数组初始

化数据很方便, 通常如果数据不需要初始化的话, 就可以用堆了)它不在栈上, 而是在附加段里. 不过这个小小

的例子有些微欠妥, 就是在栈上分配的太多, 在 VC 等可以编译 PE 文件的环境下编译可以通过, 但是运行会

出错. 而且, 显然, 在 TC 等可以编译 DOS 程序的环境下, 编译都不会通过的, 即使将内存模式设置为 HUGE.

2006-5-28 09:09
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 48 楼』:  

所以, 除了零星的小东西, 我不会使用栈, 毕竟它还有点点宝贵, 否则, 递归是不用限制的.

不过 GDI 既然是  MS 这样的巨头搞出来的, 应该有它的道理或"苦衷", 而且它也在发展, 比如后来出现的 GDI+, 在 Vista 中可能更有大的发展.  但是显然, 能真正实用的 Windows 不运行在 8086 上.

[ Last edited by jawbin on 2006-5-28 at 09:18 ]

2006-5-28 09:13
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zyl910
中级用户





积分 282
发帖 126
注册 2006-5-17
状态 离线
『第 49 楼』:  

对于栈
Windows系统默认为每个线程预留(Reserve)2MB的空间
但最开始只分配(Commit)两页(8KB)
随着递归执行,线程可能越过分配的区域,会访问到保留的区域
这时Windows系统会自动处理该异常,将访问目标那片内存提交(Commit)
保留区域的最低8KB用于越界检查(报告栈溢出异常),不可使用


注意
在栈中定义变量只是修改esp指针,不会访问实际内存
只有访问栈中变量时才是访问内存


创建线程(CreateThread)时可决定该线程 栈的大小(dwStackSize)参数
在PE文件格式中有设置栈大小的字段(IMAGE_OPTIONAL_HEADER32的SizeOfStackReserve、SizeOfStackCommit)

  Quote:
typedef struct _IMAGE_OPTIONAL_HEADER {
    //
    // Standard fields.
    //

    WORD    Magic;
    BYTE    MajorLinkerVersion;
    BYTE    MinorLinkerVersion;
    DWORD   SizeOfCode;
    DWORD   SizeOfInitializedData;
    DWORD   SizeOfUninitializedData;
    DWORD   AddressOfEntryPoint;
    DWORD   BaseOfCode;
    DWORD   BaseOfData;

    //
    // NT additional fields.
    //

    DWORD   ImageBase;
    DWORD   SectionAlignment;
    DWORD   FileAlignment;
    WORD    MajorOperatingSystemVersion;
    WORD    MinorOperatingSystemVersion;
    WORD    MajorImageVersion;
    WORD    MinorImageVersion;
    WORD    MajorSubsystemVersion;
    WORD    MinorSubsystemVersion;
    DWORD   Win32VersionValue;
    DWORD   SizeOfImage;
    DWORD   SizeOfHeaders;
    DWORD   CheckSum;
    WORD    Subsystem;
    WORD    DllCharacteristics;
    DWORD   SizeOfStackReserve;
    DWORD   SizeOfStackCommit;
    DWORD   SizeOfHeapReserve;
    DWORD   SizeOfHeapCommit;
    DWORD   LoaderFlags;
    DWORD   NumberOfRvaAndSizes;
    IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

现在虚拟机的垃圾回收机制实际上是模拟栈操作(美其名曰“内存池”)
每次创建对象时,在内存池后面的空闲空间分配一段内存出来,再修改内存池空闲空间指针。即每次都在后面分配
当发现内存池空间不够时,执行垃圾回收算法,跟踪指针,标记空闲区域
为了减少内存碎片,将后面的内存挪动到前面来,补足空闲区域,并修正指针
所以垃圾回收机制占用内存大,且垃圾回收算法很复杂,为了减少碎片还得执行内存搬运,会影响程序性能


为什么现在流行Java和.Net
这是因为现在计算机行业的应用急剧扩展
很多人抱着幻想来学编程
只想简单学一下控件使用
根本没有算法功底,更不知内存管理算法为何物
(实际上垃圾回收算法只是一种高级的内存管理算法,你可以自己编写的)


而对于操作系统
不用内存管理算法简直是笑话(没有内存管理的操作系统还能叫操作系统吗)
所以GDI对象有自己的内存分配器的,效率很高
(其实经历过windows 3.0的人都知道,那时GDI堆是64KB的。如果不注意释放的话,很容易耗尽GDI资源)


现在想学内存管理算法的话
推荐看侯捷的《STL源码解析》(算法理论书籍估计现在没人愿意看了)
STL是很好一个范本

[ Last edited by zyl910 on 2006-5-28 at 10:09 ]



人类存在的目的就是试图理解人类为何存在
2006-5-28 10:05
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
zyl910
中级用户





积分 282
发帖 126
注册 2006-5-17
状态 离线
『第 50 楼』:  

GDI+只是为适应现在的应用开发 而提出来的一个高级类库(GDI才是最根本的底层借口)
真正的图形图像处理函数都是自己《计算图形学》、《数字图像处理》算法写出来的
要不然你当GDI+的高级功能是怎么写出来的

图形程序员名言:只有能让我操作显存,我就能描绘整个世界



人类存在的目的就是试图理解人类为何存在
2006-5-28 10:08
查看资料  发送邮件  访问主页  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 51 楼』:  

zyl910 兄也终于来了!
我并没有说 GDI+ 是平地起高楼, 呵呵, 一个高级的系统是有很多层的.
我只是喜欢看上去比较优美的接口, 当然首先它不是在追求低效.而一个发展的系统,总会让它自己越来越接近自己的理想,当逐步被减少硬件上的束缚之后.所以,一个系统越往后发展,就越值得借鉴.它会越来越成熟.但是理想总是无法达到的,否则它就该改名叫现实而不是叫理想了 *^_^*
所以, 即使在 Vista 已经发售(据说已经推迟了), 它其实还没达到预期目标,至少没达到我的预期目标 :), 但是毕竟让人看到希望:这条路走得还不错,可以继续前进.

[ Last edited by jawbin on 2006-5-28 at 13:55 ]

2006-5-28 13:44
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 52 楼』:  



  Quote:
Originally posted by jawbin at 2006-5-28 09:09:
被 asbai 兄看穿了:P, 我是很看不惯 GDI
不过依据 MS 的说法, 它加速 DC 访问是用了 5 个 common DCs 中的一个用来缓存最近使用的 DC,而当这 5

个 DCs 不够 ...

引用计数自然是在同一个窗口内的DC上使用的,每个DC有自己的 reference count,一般来说,这不会降低效率。

2006-5-28 13:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 53 楼』:  

我不极力推崇底层, 因为那可以有点"无止境",最后可能追究到特定的 CPU 指令集是否最优秀了,那时候已经真正"远足"了,可以跑去设计 CPU 了.
对于一个特定追究的目标, 可以竭力去优化. 但是, 有时候复用也非常重要. 否则, 那时候出来的就不是一个通用的 intel 4004, 那目前的计算机世界是什么样子完全不可预料.

[ Last edited by jawbin on 2006-5-28 at 13:58 ]

2006-5-28 13:49
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 54 楼』:  



  Quote:
Originally posted by zyl910 at 2006-5-28 10:05:
对于栈
Windows系统默认为每个线程预留(Reserve)2MB的空间
但最开始只分配(Commit)两页(8KB)
随着递归执行,线程可能越过分配的区域@...

zyl910兄正解!

不过STL的allocator由于要考虑对象构造与析构的语义兼容,很多时候效率颇低。SGI STL的 Pool Allocator 效率尚可,但仍然有很大的优化空间。

例如:对没有构造、析构和拷贝构造问题的内置数据类型而言,用realloc的语义改变容器尺寸效率远高于创建新块;逐个拷贝旧块中的对象;释放旧块这个流程。

2006-5-28 13:53
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 55 楼』:  



  Quote:
Originally posted by asbai at 2006-5-28 01:46 PM:


引用计数自然是在同一个窗口内的DC上使用的,每个DC有自己的 reference count,一般来说,这不会降低效率。

按 MS 的说法, 应该是或者使用就近的 cache, 或者在 5 个 common DCs 中使用一个, 或者不够用的时候, 增加. 其实内部如何实现, 已经不是很重要了, 重要的是, 当我看到这样一些"矫情的"动作, 我就大倒胃口. 但是 MS 来说, 可能是"不得已", 或者说, "没什么大不了", 或者说, "没什么错". 它没有想运行在资源有限的系统上, 所以, 它完全不会遇到什么问题. 它通常面临的是 Windows 这个产品的用户的问题.

2006-5-28 13:54
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 56 楼』:  

另外,jawbin兄:

Win32为每个线程的默认保留栈空间是2MB,如果兄台将我的例子用在自己Create的一个Thread里试验,一定会有栈溢出错误。这个需要在Create的时候手动指定保留栈的尺寸。

但是Win32对每个进程的主线程是可以运行时动态调整栈空间尺寸的,应该不至于出现运行时错?

2006-5-28 13:59
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 57 楼』:  



  Quote:
Originally posted by jawbin at 2006-5-28 13:54:


按 MS 的说法, 应该是或者使用就近的 cache, 或者在 5 个 common DCs 中使用一个, 或者不够用的时候, 增加. 其实内部如何实现, 已经不是很重要了, 重要皠...

5个应该是初始值,超出以后引用计数仍然是有效的。另外,这5个貌似说的是memory dc,否是Window DC,呵呵。

这是典型的空间换时间的算法,就像 cpu 的L1/L2 cache、OS的磁盘访问缓冲等等。个人认为这确实是天经地义,不付出这点空间,换来的时间劣化是无法忍受的。

2006-5-28 14:04
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 58 楼』:  

另外,我不是想设计操作系统(至少目前是这样,因为我还没有那个能力), 我所做的, 是基于操作系统之上的. 我前面已经说过, 如果从 BIOS 起做, 对我而言太困难了:)

而且目前我所做的, 也仅仅是我自己用, 可以不用担心第三方对内存的非预期访问. 呵呵. 当然, 对于一个 platform (Java 既然不是一个 OS, 那么就把这些 runtimes 都统称为 platforms 吧), 不管理内存, 它有什么资格成为一个 platform?

2006-5-28 14:08
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
jawbin
高级用户




积分 994
发帖 444
注册 2005-1-29
状态 离线
『第 59 楼』:  



  Quote:
Originally posted by asbai at 2006-5-28 01:59 PM:
另外,jawbin兄:

Win32为每个线程的默认保留栈空间是2MB,如果兄台将我的例子用在自己Create的一个Thread里试验,一定会有栈溢出错误。这个需要在Cr ...

asbai 兄, these times, we've gone too far...
我们已经跑到"罪恶的" 640K 以外太远了, 我体力不支了

[ Last edited by jawbin on 2006-5-28 at 14:14 ]

2006-5-28 14:11
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
asbai
高级用户




积分 653
发帖 252
注册 2006-4-16
状态 离线
『第 60 楼』:  



  Quote:
Originally posted by jawbin at 2006-5-28 14:08:
另外,我不是想设计操作系统(至少目前是这样,因为我还没有那个能力), 我所做的, 是基于操作系统之上的. 我前面已经说过, 如果从 BIOS 起做, 对我而言 ...

java之类属虚拟机范畴,也就是说,它是跑在一个平台(OS)之上的平台

虽然俺也B4 VM,不过高层利用底层提供的既有功能好像是说的过去。即使OS也要利用它的底层(硬件和BIOS)所提供的既有能力嘛,哪有空中楼阁啊?

例如:硬件提供了MMU,OS就应该充分利用起来,而不是用纯软件实现分页;硬件提供了DMA控制器,OS就应该尽量用它做IO,而不应该自己实行用CPU手工搬运数据的算法~

[ Last edited by asbai on 2006-5-28 at 14:19 ]

2006-5-28 14:14
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: