⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 Delphi技巧
💻
字号:
提高 Windows 95游戏的性能问答
Microsoft公司供稿

为Windows_ 95环境开发实时游戏的一个重要问题是,避免在Windows进行一些外围设备任务时游戏循环中发生阻塞或停滞。在本文中,我提出了有关由系统事件引起的其它阻塞问题的解决方案。
? 代码内存页
 问题:当调用一些函数时,游戏的性能降低了。
 
 原因:应用程序驻留在CD-ROM中,它的访问速度慢。不是所有的函数都适于装入RAM,因而那些近期不用的函数被调用时则需从CD中读取。
 
 解决方案:
 将全部应用程序装入虚拟内存中。在这种方式下,当函数被从RAM中抛弃后,它们将置于页文件中(通常称作交换文件),在那里比从CD中检索快得多。在Raymond Chen的示例代码DMDFM.C中,当你按下F2时将其全部装入内存中。( 要浏览或拷贝示例文件,请点击本文上部的链接)
? CD-ROM缓存
 问题:应用程序的速度可能由于CD-ROM缓存而下降。
 
 原因:预读缓存为实际并不需要的函数分配了内存。这样的结果是已在RAM中的函数又不得不被页交换出去。
 
 解决方案:
 将应用程序加载到前面讲到的交换文件中。
 通常,你不需要试图实现你自己的CD-ROM缓存系统。它将以类似性能干扰的方式与系统缓存进行交互作用。
? 数据内存页
 问题:当从交换文件中访问数据时性能下降,即便是应用程序已试图仅通过“走过”并“接触”的方式加载全部数据。
 
 原因:
 解释这个问题需要对Windows如何决定何时将内存块抛弃或页交换出(如,从RAM移动到交换文件)有一些了解。
 Windows 95内存管理包括一个保护机制,禁止进程使用一次内存块后将其全部忽略。考虑这样的一个问题,例如,将一个大的位图文件用作桌面墙纸。用户正在运行一个最大化的应用程序,因而位图文件被页替换出一段时间。随后,用户将该应用程序最小化。现在系统需要重新装载墙纸的位图文件以便将其画到屏幕上。如果没有保护机制,这个位图文件将会把很多页从RAM中挤掉,即便它们可能包含了一旦应用程序重载就需要使用的代码或数据。这个位图很可能在一定时间内不再需要,但它占据了大量物理内存。
 一个安全机制可以防止上述事件发生,其方法如下。当系统加载一页(在×86的机器上,一页有4K),它首先将该页置于一中间状态。在这个状态下,页面始终没有获得一个“最近访问”的时间戳,即便它被再次访问。只有当多于16页(在Windows 95中)加载时,它将被提升至完全状态。但在此时,它被标记为近期没有使用过,因而仍是在下一次需要物理内存时首先被抛弃的对象。只有当该页在提升到完全内存状态后被访问,Windows才标记它为近期使用过,并识别它为潜在的有用页并值得保留在物理内存中。
 在上述桌面墙纸的例子中,这将意味着第一个加载的页将很可能在多于16个页加载后被抛弃。每当新的一页被加载,则有一页从中间状态被提升,并有一页被抛弃。结果是装入任何尺寸的图象只需要替换掉17×4=68K的物理内存。(再次说明,该数字仅对Windows 95有效。)
 任何希望仅通过一页一页顺次加入来使Windows在物理内存中保留大的数据块的尝试都将归于失败,因为安全机制会如处理上例中的位图一样处理这些数据。
 
 解决方案:
 为了让Windows识别一重要内存页而不抛弃它,你必须在该页从中间状态提升后再次访问它。(在它提升之前访问将不会有期待的结果)。下面的函数将实现这些:
 
 /*假定pb和cb均在页边界上,并且该页的大小由GetSystemInformation()决定*/
 #define cbLag		(16 * PageSize)
 
 void MakeRegionPresent (volatile BYTE *pb, UNIT cb)
 {
 UNIT ib;
 
 Assert(((DWORD)pb & (PageSize - 1)) = = 0);
 Assert(((DWORD)cb & (PageSize - 1)) = = 0);
 
 for  (ib = cbLag; ib < cb; ib+= PageSize)
 {
 pb[ib - cbLag];
 pb[ib];
 }
 }
 
? 五分钟的暂停
 问题:在某些设置下,当系统论询网络时,它将挂起其它全部任务达五分钟之久。
 
 原因:
 通常,问题发生在当DHCP(动态主机设置协议dynamic host configuration protocol; 详细情况请参见参考文献)装入网络适配器(通常是拨号网络适配器,如,调制解调器),但网络适配器并不在装有DHCP的服务器的网络上时。通常这是由于当用户本意是允许拨号网络适配器上的DHCP,但偶然允许了物理网络适配器上的DHCP。它还可能发生在当用户在调制解调器上允许DHCP,但网络服务提供者并没有使用DHCP。
 
 解决方案:
 告诉用户依照下列指南改变网络设置:
 在控制面板中,双击网络。在设置页中的部件列表中,单击TCP/IP并单击属性按纽。在IP地址一栏中,单击指定IP地址,然后输入IP地址和你的电脑的子网掩码。(你可以通过运行WINIPCFG获得这些数据)
? 清除交换文件
问题:Windows决定该是清理交换文件的时候了并进行此工作,将开始其它应用程序。
原因: 
当Windows发现所有的应用程序都空闲时,它便决定开始进行清理,例如,一直在GetMessage状态。
解决方案:
只要你的应用程序表现出繁忙,Windows将推迟它的清理工作。不要使用一组GetMessage调用──使用PeekMessage代替,以保证消息队列始终继续。
下面的代码段显示了在主消息循环中以PeekMessage代替GetMessage的一种方法。假定每当应用程序的焦点丢失均将AppPaused Boolean设置为TRUE。这一标记确保应用程序不会在即便理论上空闲但仍继续运行PeekMessage循环的情况下,消耗CPU时间。
MSG msg;
do
	{
	if ( PeekMessage ( &msg, NULL, 0, 0, PM_REMOVE))
		{
		if ( msg.message = = WM_QUIT) break;  //唯一退出循环的途径
		TranslateMessage (&msg);
		DispatchMessage (&msg)
}
	else
	{
	if  (AppPaused) WaitMessage();
	else
		{
		//在这里进行任何不基于消息循环的处理,如动画制作
		}
	}
}
while (TRUE);
return msg.wParam;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -