zoukankan      html  css  js  c++  java
  • 局部性原理浅析——良好代码的基本素质

    开篇

     一个优秀的程序、优美的代码,一般都具有良好的局部性。简洁、高效是每个程序员的追求。了解程序的局部性,能编写出更高效的代码。

    因为有良好局部性的程序能更好的利用缓存。不过这方面的只是将在以后的文章中介绍。

    这篇文章就简单的介绍以下程序的局部性原理。

    什么是局部性

    局部性通常有两种形式:

    时间局部性(temporal locality)

    时间局部性指的是:被引用过一次的存储器位置在未来会被多次引用(通常在循环中)。

    空间局部性(spatial locality)

    如果一个存储器的位置被引用,那么将来他附近的位置也会被引用。

    (这样说过于理论了些,在下面的论述中会有例子说明)

    数据引用局部性

    例子是最好说明问题的途径~

    看图a)中的 for 循环,可以判断:循环中的 sum 有良好的时间局部性。因为在for循环结束之前,每次执行循环体都有对 sum 的访问。

    而 sum 没有空间局部性。因为sum 是标量(也就是说通过 sum 这个地址(可认为是基址,只能得到一个值)

    对于循环体中的 v 则有良好的空间局部性。可以看到 图 b) 中,向量 v 是按顺序存储的(在实际中多数情况也按顺序存储)。

    每次访问 v[i]总是在 v[i-1] 的下一个位置。而 v 没有时间局部性。因为每个元素只被访问一次。

    步长

    向上面例子中按顺序、连续的对 v 的引用,我们称为步长为1的引用模式。同理,在一个连续的向量中,每隔k个元素对向量进行访问,称为步长为k的引用。一般来说,随着步长的增加,空间局部性会下降。

    对于多维数组而言,步长对空间局部性的影响显得尤为重要。

    考虑上面的例子,是对一个二维数组的求和。

    可以看到,for循环体中,是以行序为主序对元素进行遍历。也就是说内层循环先访问第一行的元素,然后第二行。。。

    图 b)中是二维数组存储情况。可以看出,在存储器中也是按照行序为主序来进行存储的。也就是说先存储第一行,然后第二行。。。

    现在我们已经知道了,本例中存储顺序和访问顺序一致。所以可以该程序对a[][]的引用有良好的空间局部性。

    对a[][]实行的是步长为1 的引用。

    继续看下面的例子:

    可以看出,相对于上面的例子,该例的for 循环中交换了 索引 i j 的位置。

    也就是说在对a[][]进行遍历的时候,以列序为主序。即先访问第一列,在访问第二列。。。

    而b)中,对a[][]的存储仍是行序为主序。这意味着没访问一个元素,就要跳过k个存储器才能访问下一个。于是得到一个简单的结论:该例中对a[][]的访问是以步长为k 的模式(k 为每行的元素个数)没有良好的时间局部性。

    通过上面的例子我们知道:在对向量的访问中,如果访问数序和存储顺序一致,并且是连续访问,那么这种访问具有良好的空间局部性。

    取指令的局部性

     指令存在于存储器中,cpu 要读指令就必须取出指令。所以也能评价对于取指令的局部性。

    在for 循环中,循环体内的指令多次被执行,所以有良好的时间局部性。

    循环体中的指令是桉顺序执行的,有良好的空间局部性(指令在存储器中是顺序存放的)。

    局部性小结

     评价局部性的简单原则:

    1、重复引用同一个变量有良好的时间局部性

    2、对于步长为k 的引用的程序,步长越小,空间局部性越小。步长为1 的引用具有良好的空间局部性。k越大,空间局部性越差。

    3、对于取指令来说、循环有较好的时间和空间局部性。

    后记

    这篇文章只是简单的介绍了什么是局部性,局部性原理的应有,即为什么有良好局部性的程序有更好的性能,局部性和告诉缓存的关系是如何的,将在后面的文章中介绍。这篇文章且当作后文的铺垫吧。

    本人认知有限,如上述文章有不足之处欢迎指正交流。

    参看资料:computer systems

    如有转载请注明出处:http://www.cnblogs.com/yanlingyin/

    一条鱼、yanlingyin@ 博客园 2012-2-11

     E-mail:yanlingyin@yeah.net

  • 相关阅读:
    帝国 标签模板 使用程序代码 去除html标记 并 截取字符串
    iis6 伪静态 iis配置方法 【图解】
    您来自的链接不存在 帝国CMS
    帝国cms Warning: Cannot modify header information headers already sent by...错误【解决方法】
    .fr域名注册 51元注册.fr域名
    帝国网站管理系统 恢复栏目目录 建立目录不成功!请检查目录权限 Godaddy Windows 主机
    星外虚拟主机管理平台 开通数据库 出现Microsoft OLE DB Provider for SQL Server 错误 '8004' 从字符串向 datetime 转换失败
    ASP.NET 自定义控件学习研究
    CSS层叠样式表之CSS解析机制的优先级
    ASP.NET程序员工作面试网络收藏夹
  • 原文地址:https://www.cnblogs.com/yanlingyin/p/2347116.html
Copyright © 2011-2022 走看看