这两天在对一个服务器做压力测试时,CPU使用率一直很高,保持在170%(双核)左右,很不可思议。因为程序的逻辑是非常简单的。定位半天终于发现罪魁祸首竟然在调用memset()上。注释掉所有的memset,CPU使用率一下就降到10%一下。令人非常惊讶。

对于memset的使用,基于“定义变量并严格初始化”这条黄金法则。所以,每次使用一块内存时都很小心的初始化它,以防止某些意外错误的发生。但却不知道memset()初始化大块内存时,耗费吓人!其实我们只要流程上控制好,根据需要采取首位或所需最后位补0的方法,也是可以搞定这个事情的。

具体可以见下面这段测试程序:

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

#define BUF_LEN  (1024*1024)
#define TIMES     512

double use_noset()
{
timeval timestart,timeend;
gettimeofday(&timestart, NULL);

for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
for(int j = 0; j < BUF_LEN; j++)
{
buff[j] =0;
}
delete[] buff;
}

gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec);    //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec);       //unit S
double time = linEnd-linStart;
return time;

}

double use_memset()
{
timeval timestart,timeend;
gettimeofday(&timestart, NULL);

for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
memset(buff,0,BUF_LEN);
delete[] buff;
}

gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec);    //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec);       //unit S
double time = linEnd-linStart;
return time;
}

double use_setlast()
{
timeval timestart,timeend;
gettimeofday(&timestart, NULL);

for( int i = 0; i < TIMES; i ++)
{
char* buff = new char[BUF_LEN];
buff[BUF_LEN-1] = ‘\0′;
delete[] buff;
}

gettimeofday(&timeend, NULL);
double linStart = 0,linEnd = 0;
linStart = ((double)timestart.tv_sec * 1000000 + (double)timestart.tv_usec);    //unit S
linEnd = ((double)timeend.tv_sec * 1000000 + (double)timeend.tv_usec);       //unit S
double time = linEnd-linStart;
return time;
}

int main(int argc, char** argv)
{
double t1 = use_noset();
double t2 = use_memset();
double t3 = use_setlast();
printf(”no memset used =%f, memset used t2= %f, no memset used t3=%f,t1/t2=%f t2/t3=%f\n”, t1, t2, t3,(t1/t2), (t2/t3));
}

跑出来的结果是:
no memset used =2118321.000000, memset used t2= 102161.000000, no memset used t3=37.000000,t1/t2=20.735124 t2/t3=2761.108108

从结果可以看出,memset(),比直接给每个字节赋值要快20倍,但跟后位置零相比,整整慢了近3k倍。如果运行高并发的程序这种效率就很要人命。

教条主义真是害人。多动手实践,不要做多余的事情,控制好你的程序才是最关键的。

Tags: .
首页

No Comments Now!

Be the first to comment on this entry.

请您留下评论

名称(必填)
Mail (必填),(will not be published)
网站(recommended)

Fields in bold are required. Email addresses are never published or distributed.

Some HTML code is allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
URLs must be fully qualified (eg: http://www.hongzhixiong.com),and all tags must be properly closed.

Line breaks and paragraphs are automatically converted.

Please keep comments relevant. Off-topic, offensive or inappropriate comments may be edited or removed.