VB 源码VC 源码ASP源码JSP源码PHP源码CGI源码FLASH源码素材模板C 源程序常用软件文档中心其他程序

软件使用

网站服务
邮件服务
网络应用
软件使用

本类阅读TOP10

·提高BT下载速度全攻略之优化配置BitComet
·注册码大全
·恢复硬盘数据
·Real Player10使用技巧
·如何抢救损坏的ZIP文件?
·教你如何修改文件日期
·四招打造Excel函数高手
·光盘超容量刻录的原理和操作方法
·让FlashGet帮你修复VCD光盘
·光盘刻录知识全集

精品推荐
精彩教程:快速初始化内存(1)

作者:佚名 来源:月光软件站 加入时间:2005-3-1 月光软件站

许多计算密集型的应用都需要处理大量内存,这种应用中的内存初始化是一个常规操作,而内存和CPU内部的数据交换之间的速度瓶颈决定了内存初始化将会占用可观的时间。但因为应用程序初始化内存往往调用CRT的memset或者Windows API的ZeroMemory,很少有人在初始化方面进行优化。
  
  另一方面,现在的应用硬件一般配置都比较好,大部分应用都运行在PII之上,但我们在使用诸如VC之类的编译环境时往往选择速度优化,并选择合适的处理器,然后寄希望于编译器给我们生成优化的结果,结果往往发现并不如意。
  
  在我们的一个图像处理项目中,需要大量内存操作,而且多个线程同时运行,内存存取成为了各个模块的竞争资源,所以对内存存取优化成为项目的关键。在努力减少内存操作遍数的基础上,加快内存初始化成为我们的改进重点。
  
  在用VC各种手段都没有太多改进后,我们把目光转向处理器特征。从Pentium系列开始,一方面Intel在不断提高CPU主频,同时也在针对多媒体等应用相继推出MMX/SSE/SSE2,增加了许多多位快速处理指令。在高层语言方面,Intel的C++ Compiler提供了针对不同处理器的最优化结果。但在一个成熟项目中贸然使用另外一种编译环境的风险较大,所以我们从Intel环境中抽取了memset的实现,重新组织了一个Lib,并在我们的项目中针对内存初始化进行了改动,并链接到抽取的lib库中。在内存初始化方面有了一个较大的提高。
  
  下面我们用测试例子说明该过程。
  
  一个例子
  
  在测试程序中,分别调用微软C库的memset和intel版本的memset分别对100M内存进行60遍初始化,,为了模拟多线程环境,启动了两个线程同时进行内存初始化。测试时使用了Release版,为了方面查看包含了调试信息(调试信息无影响)。测试结果:
    
  MSC 版本:12.453~12.547秒
  
  Intel C版本:4.375~4.531秒
  
  可见在大量内存操作时差别比较大。对内存存取密集型项目,因为内存存取往往是瓶颈,应该还可以提高整体处理性能。
  
  下面是例子的代码:
  
  // 本程序示例了使用微软CRT的memset和Intel优化的memset初始化内存的速度差异
  
  // Lihw.
  
  #include
  
  #include
  
  #include
  
  extern "C"
  
  void * __cdecl __intel_new_memset(void *, int, size_t);
    
  #pragma comment(lib,"intelmem.lib")
  
  #define SIZE 1024*1024*100
  
  void threadfunc(void *dummy)
  
  {
  
   LPBYTE lpByte = (LPBYTE)dummy;//new BYTE[SIZE];
  
   int j;
  
  #define LoopTimes 60
  
   DWORD dwStart, dwTime1,dwTime2;
  
   //
  
   //intel version
  
     dwStart = GetTickCount();
   for (j=0; j< LoopTimes; j++)
  
   {
  
   __intel_new_memset(lpByte,1,SIZE);
  
   }
  
   dwTime1 = GetTickCount() - dwStart;
  
   //MS crt version
  
   dwStart = GetTickCount();
  
   for (j=0; j< LoopTimes; j++)
  
   {
  
   memset(lpByte,1,SIZE);
  
   //ZeroMemory(lpByte,SIZE);
  
   }
  
   dwTime2 = GetTickCount() - dwStart;
  
   //delete []lpByte;
  
   printf("Intel=%dms MSC=%dms\n",dwTime1,dwTime2);
  }
  
  int main(int argc, char* argv[])
  
  {
  
  #define THREADS 2
  
   HANDLE hThread[THREADS]; //array to hold thread handle
  
   LPBYTE lpByte[THREADS]; //Array to hold thread-specific memory
  
   int i;
  
   //Count mem alloc time. Debug version is very long
  
   DWORD dwStart = GetTickCount();
  
   for (i=0; i   
   {
  
   lpByte[i] = new BYTE[SIZE];
  
   }
  
   printf("Alloc spend=%d\n",GetTickCount() - dwStart);
  
  //Start thread
    
   for (i=0; i   
   hThread[i] = (HANDLE)_beginthread( threadfunc, 0, lpByte[i] );
  
  //threadfunc(lpByte[i]);

   WaitForMultipleObjects(THREADS,hThread,TRUE,INFINITE);
  
   for (i=0; i   
   delete []lpByte[i];
  
   printf("Process Exec time=%dms\n",GetTickCount() - dwStart);
  
   return 0;
  
  }
  
  让我们来看看究竟上什么造成这么大的差别。在Release版本的__intel_new_memset处和memset处设置断点,打开反汇编窗口:

  Intel版本:

  31: for (j=0; j< LoopTimes; j++)
  
  32: {
  
  33: __intel_new_memset(lpByte,1,SIZE);
  
  00401017 push 6400000h
  
  0040101C push 1
  
  0040101E push ebx
    
  0040101F call ___intel_new_memset (00401110)

    00401024 add esp,0Ch

    00401027 dec esi

      00401028 jne threadfunc+17h (00401017)
  
  34: }



相关文章
  • PostgreSQL 7.2 教程 (1)
  • PostgreSQL 7.2 教程 (2)
  • 简明批处理教程
  • SQL Server 2000企业版安装教程
  • 黑客技术:SQL入侵教程
  • Apache 服务器的安装教程
  • Helix流媒体服务器架设及RMVB制作教程
  • 快速打造留言本教程[1]
  • 教程:利用PS的3D渲染构造页面元
  • Fireworks 制作闪存盘效果教程
  • 鼠标效果系列教程(四)鼠标踪迹
  • 鼠标效果系列教程(三)游动的鱼
  • 鼠标效果系列教程(二)简单跟随
  • 鼠标效果系列教程(一)个性指针
  • FTP服务器的架设教程
  • 教你如何架设个人服务器--全教程
  • 一流的设计师,一流的PHOTOSHOP教程
  • Photoshop路径终极教程
  • 相关软件

  • Photoshop中文教程
  • C 语言教程  
  • 超级文本C++教程  
  • 操作符重载C++教程  
  • TURBO C教程  
  • 功能强大的 TC 教程  
  • CUG输入编缉,打字教程的C语言源程序  
  • C语言教程  
  • TURBO-C 教程的C语言源码  
  • PHP中文教程  



  • 月光软件程序下载编程文档电脑教程网站设计网址导航网络文学游戏天地幽默笑话生活休闲写作范文安妮宝贝
    电脑技术编程开发网络专区谈天说地情感世界游戏元素分类游戏热门游戏体育运动手机专区业余爱好影视沙龙
    音乐天地数码广场教育园地科学大观古今纵横谈股论金人文艺术医学保健动漫图酷二手专区地方风情各行各业

    月光软件站·版权所有