快速初始化内存(1)

原创 2004年05月10日 12:19:00

快速初始化内存

 

许多计算密集型的应用都需要处理大量内存,这种应用中的内存初始化是一个常规操作,而内存和CPU内部的数据交换之间的速度瓶颈决定了内存初始化将会占用可观的时间。但因为应用程序初始化内存往往调用CRTmemset或者Windows APIZeroMemory,很少有人在初始化方面进行优化。

<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

另一方面,现在的应用硬件一般配置都比较好,大部分应用都运行在PII之上,但我们在使用诸如VC之类的编译环境时往往选择速度优化,并选择合适的处理器,然后寄希望于编译器给我们生成优化的结果,结果往往发现并不如意。

 

在我们的一个图像处理项目中,需要大量内存操作,而且多个线程同时运行,内存存取成为了各个模块的竞争资源,所以对内存存取优化成为项目的关键。在努力减少内存操作遍数的基础上,加快内存初始化成为我们的改进重点。

 

在用VC各种手段都没有太多改进后,我们把目光转向处理器特征。从Pentium系列开始,一方面Intel在不断提高CPU主频,同时也在针对多媒体等应用相继推出MMX/SSE/SSE2,增加了许多多位快速处理指令。在高层语言方面,IntelC++ Compiler提供了针对不同处理器的最优化结果。但在一个成熟项目中贸然使用另外一种编译环境的风险较大,所以我们从Intel环境中抽取了memset的实现,重新组织了一个Lib,并在我们的项目中针对内存初始化进行了改动,并链接到抽取的lib库中。在内存初始化方面有了一个较大的提高。

 

下面我们用测试例子说明该过程。

一个例子

 

在测试程序中,分别调用微软C库的memsetintel版本的memset分别对100M内存进行60遍初始化,,为了模拟多线程环境,启动了两个线程同时进行内存初始化。测试时使用了Release版,为了方面查看包含了调试信息(调试信息无影响)。测试结果:

 

MSC 版本:12.453~12.547

Intel C版本:4.3754.531

 

可见在大量内存操作时差别比较大。对内存存取密集型项目,因为内存存取往往是瓶颈,应该还可以提高整体处理性能。

 

下面是例子的代码:

 

 

// 本程序示例了使用微软CRTmemsetIntel优化的memset初始化内存的速度差异

//  Lihw.

 

#include <stdio.h>

#include <windows.h>

#include <PROCESS.H>

 

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<THREADS;i++)

       {

              lpByte[i] = new BYTE[SIZE];

       }

 

 

       printf("Alloc spend=%d/n",GetTickCount() - dwStart);

      

       //Start thread

       for (i=0; i<THREADS;i++)

              hThread[i] = (HANDLE)_beginthread( threadfunc, 0, lpByte[i] );

              //threadfunc(lpByte[i]);

        

        WaitForMultipleObjects(THREADS,hThread,TRUE,INFINITE);

 

       for (i=0; i<THREADS;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:       }

 

memset初始化内存

  转载:http://www.cnblogs.com/lebronjames/archive/2010/07/04/1770987.html 功能: 将s所指向的某一块内存中的每个字节的内...
  • haohao1945
  • haohao1945
  • 2016年05月16日 16:03
  • 242

C语言内存的初始化

我们编写C语言的时候需要给变量申请一块内存区域,当我们创建一个内存区域的时候,内存中的数据十有八九是乱七八糟的(因为其他代码用过后遗留的数据并没有及时清掉) 例如: int main() { ...
  • baidu_34919559
  • baidu_34919559
  • 2016年05月08日 02:17
  • 1061

嵌入式学习-uboot-lesson7-内存初始化

6410所使用的内存为DDR 210使用的是DDR2 2440使用的是SDRAM,关于他们之间的区别,我在以前的文章中ok6410内存及启动流程简单介绍过,有兴趣的可以看看。1. 地址空间S3C641...
  • u011003120
  • u011003120
  • 2016年06月28日 18:41
  • 2176

Linux内核---41.arm 内存初始化

Linux内核---41.arm 内存初始化
  • wangcong02345
  • wangcong02345
  • 2016年07月09日 10:20
  • 813

malloc到未初始化的内存

在最近开发过程中发现一个malloc到未初始化内存的错误. 在使用CLISH(一款命令行开源软件)的时候,每次这个程序退出的时候都会发生core dump,错误为invalid pointer: 0...
  • realduke2000
  • realduke2000
  • 2016年09月20日 09:41
  • 693

从头认识java-4.8 数组的初始化(1)

这一章节我们来讨论一下数组的初始化。1.数组是一个对象。package com.ray.ch01; public class Test { public static void main(Stri...
  • raylee2007
  • raylee2007
  • 2015年10月28日 08:28
  • 1941

Uboot 内存初始化(2440)

Uboot 内存初始化(2440) 内存分类,DRAM:需要定期充电(刷新),否则数据会丢失,存取速度慢。SRAM:具有静止存储功能的内存,不需要定期刷新操作就能保存它内部存储的数据,存取速度快,C...
  • A3203211
  • A3203211
  • 2014年03月13日 21:49
  • 1479

启动期间的内存管理之build_zonelists初始化备用内存域列表zonelists--Linux内存管理(十三)

日期 内核版本 架构 作者 GitHub CSDN 2016-06-14 Linux-4.7 X86 & arm gatieme LinuxDeviceDrive...
  • gatieme
  • gatieme
  • 2016年09月01日 22:31
  • 1922

C语言中的初始化及内存分配

http://blog.csdn.net/juana1/article/details/6301544 C语言中的初始化及内存分配 分类: VC编程2011-04-04 16:23...
  • wangyin159
  • wangyin159
  • 2014年08月08日 11:07
  • 887

Java基础-对象的内存分配与初始化

首先,什么是类的加载?类的加载由类加载器执行.该步骤将查找字节码(classpath指定目录),并从这些字节码中创建一个Class对象。java虚拟机为每种类型管理一个独一无二的Class对象。也就是...
  • Wang_1997
  • Wang_1997
  • 2016年08月21日 13:49
  • 1060
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:快速初始化内存(1)
举报原因:
原因补充:

(最多只允许输入30个字)