起步于系统工程师,迈进入测试工程师,从起初的C/S系统到互联网时代的B/S系统,从事过电信增值业务、软交换、烟草OA、公安技侦和电子商务等行业的软件测试开发和管理多年,愿与大家共同分享共同交流,关注软件项目管理、测试团队管理、软件流程控制和软件性能测试及自动化测试技术。互联网时代,技术推动进步,欢迎人才推荐:jonas.wangl@alibaba-inc.com

【linux】page cache 和VM Perl 线程和C++性能优化

上一篇 / 下一篇  2010-03-24 11:35:27 / 个人分类:Linux/unix

4Fc6l9Clm'IU ikt0调节Page Cache

nb0^-x9bm6L,I;d2~051Testing软件测试网)b O|CW:R?

Linux的内核中,对文件的读写提供一个页面缓冲的机制(Page Cache)。Page Cache存在于内存中,当要读取一个磁盘文件的内容时,内核首先在Page Cache中进行查找,如果要读取的内容已经存在Page Cache中,则无需在对磁盘发起实际的读操作。同样在需要写文件时,写操作也只是将内容存放于Page Cache中,而Page Cache中的更改内容由内核进程pdflush周期性的写回磁盘。在默认情况下,pdflush进程每5秒钟醒来一次,进行数据写回操作。这个写回时间值定义在参数/proc/sys/vm/dirty_writeback_centisecs中。如果在这5秒钟之间,发生电源故障或者系统崩溃,可能会引起数据丢失。如果用户的电源供应比较可靠,或者丢数据丢失的风险不是非常在意,可以适当的提高这个数据写回时间。使用如下命令查看系统当前的写回时间值:

7UT!S"@M;}&f#?0

cat /proc/sys/vm/dirty_writeback_centisecs51Testing软件测试网7s.sn ^;[3E qQ s

 500

*v/i:~]O:e'A0

 51Testing软件测试网-Tu*a/Brvq

此时间值的单位为1/100秒。使用如下命令可以更改此值:51Testing软件测试网/H'S` NPf

 echo 2000 > /proc/sys/vm/dirty_writeback_centisecs

0?.V1a;z#wB+r3F5[0

 51Testing软件测试网+sl}Q&I'is5`0b8\j`

这样,就可以使pdflush进程20秒才醒来一次,从而减少对磁盘的访问频率。

$U @8E;g_,fn$N$mzv T7V0

还有一个参数/proc/sys/vm/dirty_expire_centisecs控制一个更改过的页面经过多长时间后被认为是过期的、必须被写回的页面,其默认值是3000(单位也是1/100秒)。用户也可以适当的增加此值,使页面更长时间的驻留在内存中。如下命令:

.f*aJ g:s&P0

 echo 4000 > /proc/sys/vm/dirty_expire_centisecs51Testing软件测试网:|/{.QrA^C

 

%x-m8`y/Ok'm9qo0

pdflush进程处理的另一种情况是当可用内存量降低的时候,会将一些缓冲页面写回磁盘,释放内存。这个行为是受/proc/sys/vm/dirty_background_ratio参数控制的,此参数的默认值为10,意思是当所有被更改页面总大小占工作内存超过10%时,pdflush会开始写回工作。用户可以增加这个比例,以增加页面驻留在内存的时间。此参数的更改方法同上面两个参数。51Testing软件测试网 R|jP7Wt c

Swap分区或文件51Testing软件测试网H M7HMkJ

在 默认情况下,Linux内核并不是只有在物理内存不够用的时候才进行交换,而是为了保证尽量大的磁盘缓冲以及其他一些原因,会尽可能的将非活动的进程及内存页面交换出内存,放在磁盘上的交换分区中。这种默认行为使得在还有大量内存可用的情况下,就会发生交换操作,而释放出的物理内存并没有被利用起来,显然这些交换操作是不必要 的。为了减少因交换引起的磁盘读写,在用户内存足够大的时候,可以考虑禁用swap分区。51Testing软件测试网p4} MU3nX;On/B

显示作业和进程信息

F7ZY G;Vzc5z0

                              

9Wk(k(odEy0

ian@attic4:~$jobs -l

]l^dq Y~W0

[1]-  3878 Running                 xclock -d -update 1 &51Testing软件测试网 Ov)gl_,i,s

[2]+  4320 Running                 xclock -bg wheat -update 1 &51Testing软件测试网2l l(f^.^}@@#J

 51Testing软件测试网:iy(J&d2u&C R6j6S

线程概述51Testing软件测试网/r6G!_W4Y0s1U&L$[

线程与进程之间既有联系,又完全不同。简单地说,一个线程必然属于某一个进程,而一个进程包含至少一个或者多个线程。

@(]j1yV3A-x0

 

*~"s(Wz(zq8W0

 51Testing软件测试网(Q H%G`6Lm [6t

  1. Perl程序中,我们也可以通过使用Config模块来动态获取Perl线程模型的相关信息,例如


)ir:F6y/^ X0Perl
程序中动态获取当前Perl线程模型51Testing软件测试网 K+@3X6LGo BK

                              

'cbg$kv [#y Q+I;W0

 #!/usr/bin/perl51Testing软件测试网1O\,PP4z-a^z

 #51Testing软件测试网dz%Sn_9Q!_9QyI

 use Config;51Testing软件测试网k"KG ?"^!V6`M;NY

 if( $Config{useithreads} ) {51Testing软件测试网},F/{0?*b#CI8H.j{

 printf("Hello ithreads\n")51Testing软件测试网6L[7O.t7ge6BV

 }51Testing软件测试网,AZ,t/fq%eD'D

 elsif( $Config{use5005threads} ) {

{&|0KK9b+x/~ A {0

 printf("Hello 5005threads\n");51Testing软件测试网G T!U%z"^

 }51Testing软件测试网2I5~\3n+oBG-A~lb

 else {

Ej@+z@0M1D2_s({0

 printf("Can not support thread in your perl environment\n");

bTAh!@ Y7D0

    exit( 1 );

L${ a2ZoO0

 }

/n y+U)G_$n"b0

 

s FbqL {$kx-s0

 

#y%T(y"d2Gz`0

创建线程

4Z4od5}#bqlg:s0

Perl里创建一个新的线程非常简单,主要有两种方法,他们分别是:

-k`'_#Q'dj$Z0
  1. 使用threads包的create()方法,例如

51Testing软件测试网L;`jiVKGa,N*\J
1)
通过create()方法创建线程

e:QFAI&?0

                              

bq7h*R||Y0

 use threads;51Testing软件测试网^hjiS'l"L

 51Testing软件测试网c4o&AU9\S:@I

 sub say_hello

Zms(k!L4}D-i,r5[n0

 {

]8hi;cR{0

    printf("Hello thread! @_.\n");

/G&|wV!De4Z0

 return( rand(10) );

!Q ~2{V$A_s?0

 }

r(T+x{9NL;h$M-E'Ih0

 

}G3AB'}6amFs0

 my $t1 = threads->create( \&say_hello, "param1", "param2" );51Testing软件测试网L~[(\/E!TOX

 my $t2 = threads->create( "say_hello", "param3", "param4" );51Testing软件测试网X:p~%u-g%T6Q7f_"@G

 my $t3 = threads->create(51Testing软件测试网1b@C ?9`X)H ~M

 sub {

}~V*l?,`-x7dg/\0

 printf("Hello thread! @_\n");51Testing软件测试网,z!MI9D?ih,`

                 return( rand(10) );51Testing软件测试网 w;y-D+g,hek

 },51Testing软件测试网n!wylz

 "param5",

.M%F*u7X;o hZ8Q0

             "param6" );51Testing软件测试网^f7Qw2O2oj,oi`

 

J;~{%r |0
  1. 使用async{}块创建线程,例如

51Testing软件测试网 ~Fk UE&]0M
2)
通过async{}块创建线程51Testing软件测试网*d|sp cG7A%\

                              

8To0OANi*F c%U9}0

 #!/usr/bin/perl

,yH W S fl8@O.b0

 #51Testing软件测试网)iiZ V(s7i*o0kfbN:A

 use threads;

zZ+s;i;S-LM8E0

 

1l^1y(p[It)d2C0

 my $t4 = async{51Testing软件测试网%_Fec [#gs^

 printf("Hello thread!\n");

n-^]X!?"Eh0

         };51Testing软件测试网4}0Fsb c%kC_Th

 51Testing软件测试网?h8m6oTs

 51Testing软件测试网]gV%k4z8p

析构函数与构造函数51Testing软件测试网U|y:w_0H

 

g%f zK i(Gy-^x0

析构函数的调用与构造函数的调用一样,也是类似的递归操作。

2i*z)mJ H3W&n0

但有两点不同,一是析构函数没有与构造函数相对应的初始化操作部分,这样析构函数的主要工作就是执行析构函数的函数体;51Testing软件测试网*|*v'vz-c)m

二是析构函数执行的递归与构造函数刚好相反,而且在每一层的递归中,成员变量对象的析构顺序也与构造时刚好相反。51Testing软件测试网[!j4UmV2Q

 51Testing软件测试网H{&x:i(o

C++程序汇总消耗性能51Testing软件测试网|*W^y(A6v5_ S7]

C++程序中,创建/销毁对象是影响性能的一个非常突出的操作。

4bP*H1CS)c%vS0

首先,如果是从全局堆中生成对象,则需要首先进行动态内存分配操作。众所周知,动态内存分配/回收在C/C++程序中一直都是非常费时的。因为牵涉到寻找匹配大小的内存块,找到后可能还需要截断处理,然后还需要修改维护全局堆内存使用情况信息的链表等。因为意识到频繁的内存操作会严重影响性能的下降,所以已经发展出很多技术用来缓解和降低这种影响,比如内存池技术。其中一个主要目标就是为了减少从动态堆中申请内存的次数,从而提高程序的总体性能。当取得内存后,如果需要生成的目标对象属于一个复杂继承体系中末端的类,那么该构造函数的调用就会引起一长串的递归构造操作。在大型复杂系统中,大量此类对象的创建很快就会成为消耗CPU操作的主要部分。因为注意和意识到对象的创/销毁会降低程序的性能,所以开发人员往往对那些会创建对象的代码非常敏感。在尽量减少自己所写代码生成的对象同时,开发人员也开始留意编译器在编译"悄悄"生成的一些临时对象。开发人员有责任尽量避免编译器为其程序生成临时对象,下面会有一节专门讨论这个问题。语义保持完全一致。51Testing软件测试网,m:NdwJ-plP


TAG:

 

评分:0

我来说两句

Open Toolbar