学习网考试学习资料

Gzu521.com

提高Linux系统性能加速网络应用程序(2)

LINUX教程   点击:次   发布时间:2006-10-17   【字体: 】   来源:Gzu521.com
Gzu521.com我的学习网


  技巧 2. 最小化系统调用的负载  

  任何时候通过一个 socket 来读写数据时,您都是在使用一个系统调用(system call)。这个调用(例如 read 或 write)跨越了用户空间应用程序与内核的边界。另外,在进入内核之前,您的调用会通过 c 库来进入内核中的一个通用函数(system_call())。从 system_call() 中,这个调用会进入文件系统层,内核会在这儿确定正在处理的是哪种类型的设备。最后,调用会进入 socket 层,数据就是在这里进行读取或进行排队从而通过 socket 进行传输的(这涉及数据的副本)。  

  这个过程说明系统调用不仅仅是在应用程序和内核中进行操作的,而且还要经过应用程序和内核中的很多层次。这个过程耗费的资源很高,因此调用次数越多,通过这个调用链进行的工作所需要的时间就越长,应用程序的性能也就越低。  

  由于我们无法避免这些系统调用,因此惟一的选择是最小化使用这些调用的次数。幸运的是,我们可以对这个过程进行控制。  

  解决方案  

  在将数据写入一个 socket 时,尽量一次写入所有的数据,而不是执行多次写数据的操作。对于读操作来说,最好传入可以支持的最大缓冲区,因为如果没有足够多的数据,内核也会试图填充整个缓冲区(另外还需要保持 tcp 的通告窗口为打开状态)。这样,您就可以最小化调用的次数,并可以实现更好的整体性能。 

  技巧 3. 为 bandwidth delay product 调节 tcp 窗口  
  tcp 的性能取决于几个方面的因素。两个最重要的因素是链接带宽(link bandwidth)(报文在网络上传输的速率)和 往返时间(round-trip time) 或 rtt(发送报文与接收到另一端的响应之间的延时)。这两个值确定了称为 bandwidth delay product(bdp)的内容。  

  给定链接带宽和 rtt 之后,您就可以计算出 bdp 的值了,不过这代表什么意义呢?bdp 给出了一种简单的方法来计算理论上最优的 tcp socket 缓冲区大小(其中保存了排队等待传输和等待应用程序接收的数据)。如果缓冲区太小,那么 tcp 窗口就不能完全打开,这会对性能造成限制。如果缓冲区太大,那么宝贵的内存资源就会造成浪费。如果您设置的缓冲区大小正好合适,那么就可以完全利用可用的带宽。下面我们来看一个例子:bdp = link_bandwidth * rtt如果应用程序是通过一个 100mbps 的局域网进行通信,其 rrt 为 50 ms,那么 bdp 就是:100mbps * 0.050 sec / 8 = 0.625mb = 625kb注意:此处除以 8 是将位转换成通信使用的字节。  

  因此,我们可以将 tcp 窗口设置为 bdp 或 1.25mb。但是在 linux 2.6 上默认的 tcp 窗口大小是 110kb,这会将连接的带宽限制为 2.2mbps,计算方法如下:  

  throughput = window_size / rtt  

  110kb / 0.050 = 2.2mbps  

  如果使用上面计算的窗口大小,我们得到的带宽就是 12.5mbps,计算方法如下:  

  625kb / 0.050 = 12.5mbps  

  差别的确很大,并且可以为 socket 提供更大的吞吐量。因此现在您就知道如何为您的 socket 计算最优的缓冲区大小了。但是又该如何来改变呢? 

  解决方案  

  sockets api 提供了几个 socket 选项,其中两个可以用于修改 socket 的发送和接收缓冲区的大小。清单 2 展示了如何使用 so_sndbuf 和 so_rcvbuf 选项来调整发送和接收缓冲区的大小。  

  注意:尽管 socket 缓冲区的大小确定了通告 tcp 窗口的大小,但是 tcp 还在通告窗口内维护了一个拥塞窗口。因此,由于这个拥塞窗口的存在,给定的 socket 可能永远都不会利用最大的通告窗口。  

T!}wVjP p ( 贵.州,学.习,网 电脑课堂LINUX教程 )T!}wVjP phTTp://wWw.gZu521.cOm
int ret, sock, sock_buf_size;  

sock = socket( af_inet, sock_stream, 0 );  

sock_buf_size = bdp;  

ret = setsockopt( sock, sol_socket, so_sndbuf,  
                   (char *)&sock_buf_size, sizeof(sock_buf_size) );  

ret = setsockopt( sock, sol_socket, so_rcvbuf,  
                   (char *)&sock_buf_size, sizeof(sock_buf_size) );  

上 一 页 下 一 页
4页: 第 [1] [2] [3] [4]

责任编辑:gzu521

电脑课堂分类
Windows 2000教程
Windows XP教程
Windows 2003教程
Windows Vista教程
LINUX教程
软件教学
办公软件
硬件DIY
分类推荐信息
更多...
大类最新文章
更多...