您的位置:首页精文荟萃软件资讯 → 精彩教程:快速初始化内存(1)

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

时间:2004/10/7 18:29:00来源:本站整理作者:蓝点我要评论(0)


            
             
              
             
            

               
               

            



            

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

相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本