| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> 应用开发 >> vc >> VC实例 >> 文章正文
精彩教程:快速初始化内存(1)        【字体:
精彩教程:快速初始化内存(1)
作者:-    文章来源:-    点击数:    更新时间:2006-4-20

  许多计算密集型的应用都需要处理大量内存,这种应用中的内存初始化是一个常规操作,而内存和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,INFIN99vE);

   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: {

[1] [2] 下一页  

文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • Windows网络编程经典入门

  • 制作自动循环播放的MP3播放器…

  • ping的源程序

  • 制作自动循环播放的MP3播放器…

  • 明明白白看MFC之程序框架(一…

  • 使用GDI在内存中转换图片类型

  • 扩展MFC类库建立自己的界面类…

  • 在BMP文件中隐藏信息(一)

  • VC下ADO开发实践之一

  • 明明白白看MFC之程序框架(二…

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |