[上一页]
[下一页]
1.1.2 伸缩性和性能
1.1.2 伸缩性和性能
在早期的编程中,程序员只能得到有限的系统资源。这迫使程序员编写巧妙但无法维护的算法来尽可能多地弥补系统性能的不足。今天的计算机系统性能及存储容量已极大地提高了,允许程序员设计简单且易于维护的算法。
不幸的是,这些进步让程序员变得懒惰了。我知道有些程序员随便为顶多只需要几KB的任务分配数MB的存储空间,甚至不多考虑一下。我也知道有些程序员在临界区足以胜任的地方使用互斥对象。这些程序员完全未考虑到访问一个互斥对象的函数要在用户模式和核心模式之间来回切换,这需要大约1000个CPU时钟周期——还不包括在核心模式必须执行一次的代码。与之对比,临界区通常完全处在用户模式中且只需大约100个CPU时钟周期来执行。 越来越多的人正在使用计算机,因为它的服务提供了信息来改善我们的生活质量。研究表明用户对响应缓慢的服务容易变得失望,转而到其它的地方搜索期望的信息,这转化成为商业和税收上的损失。同样地,一个企业的信息服务不能及时响应也会使员工感到失望并最终影响生产力——这也转化成为商业和税收上的损失。 某些情况下,你可以通过增加更多的计算机来提高服务器的响应能力。然而由于很多原因,你往往需要状况良好地运行你的服务程序于一台单独的服务器上。第一,编写在不同的计算机上运行其各个部件的服务程序要比编写只运行于一台计算机上的软件要难得多。第二,管理多台计算机的复杂性常常以“超线性”的比率增加。第三,(多计算机让)你引入了几个较隐蔽的故障要点,使错误更难于定位和纠正。“只使用一台单独的服务器”不是总可以实现的,但你在编写服务程序代码时要紧记这个理念。 对于单机服务器,可以通过增加RAM、处理器、磁盘存储、网卡等来增进性能,但仅当你的服务程序代码是按照运用这些资源的有效方式编写的。例如,按照一个客户一个连接线程的服务程序,通常不会因简单地将机器RAM容量翻倍而成倍地提高性能。然而,如果在同样的服务器上使用一种高效的线程池算法设计程序,服务器的性能将随硬件资源的增加而扩伸。
编写高伸缩性的程序需要遵循很多规则。在每个一步骤中,你必须考虑自己所写的代码的效果:
■ 是否编写这些代码就可以避免从用户模式到内核模式的转换? ■ 是否对齐了对内存的访问以使它不会跨越cache-line的边界? ■ 是否确定变量都是完全被对齐的? ■ 是否用线程替换了进程以减少系统资源的占用? ■ 是否减少了可运行的线程数量以避免不必要的线程上下文切换? ■ 是否让线程在等待设备I/O操作完成时也做有用的工作? ■ 是否舍弃了ANSI串而宁愿使用Unicode串以提高Windows函数的性能? ■ 是否使用了Windows提供的更“酷”的功能?
我在此提到的这些问题希望你在编写代码的时候能牢记于心。其中的每项规则在 《Programming Applications for Microsoft Windows, Fourth Edition》或本书中都有详细的讨论。
|