최적화의 모든 종류의 초석 - 지역의 원리

컴퓨터의 기본 원칙을 공부, 또는 아키텍처의 많은이 학생들을 최적화하기위한 것입니다에 대한 지역의 원리를 잘 알고 있어야 찾을 수 있습니다. 지역화 된 때 효력을 가지고 가야 또한 언급, 튜닝의 모든 종류의 일을하더라도 비 컴퓨터 산업,하지만 그들은 일반적으로 단어 지역을 사용하지 않습니다. 이러한 우주의 엔트로피 분포 레이아웃, 낮은로 인해 지역 엔트로피, 때문에 추상화하고, 심지어 그 높은 수준의 지구는, 삶, 모든 지역화 제품은, 우주는 모든 곳에서 엔트로피, 일부 일치 한 경우 경우 카오스.  
  그래서 무엇 지역 ? 이는 일반적인 컴퓨터 용어이다 큰 특정 데이터, 위치 데이터 또는 특정 액세스 확률을 액세스 할 때 짧은 반복 프로세서 액세스의 존재를 의미하는 시간의 대부분은 로컬 데이터 _ _ 액세스. 지역의 원칙을 바탕으로, 컴퓨터 프로세서는 멀티 레벨 캐시 현대 CPU, 분기 예측 ...... 빨리 실행하는 것보다 더 좋은 지역의 지역 절차 등 다양한 최적화를 수행하도록 설계되었습니다. 용어가 있지만, 오늘날의 분산 시스템에서 로컬 컴퓨터 디자인에서 오는 있지만, 인터넷 기술은 ...... 백 엔드에 압력을 완화하기 위해이 레디 스의 memcache에와 같이, CDN 배포 물질은 대역폭 사용량을 줄이기 위해 무엇을, 어떤 지역을 찾을 수 있습니다
  소재지 본질은 무엇인가? 사실 불평등 등 확률,이 우주에서, 많은 것들을 균등 확률 이론의 평균 분포, 기하 분포의 특별한 형태는 매우 간단하지만, 세상은 그렇게 간단하지 않다, 배포되지 않습니다. 우리는 더 이상 출시가 가우스 릴리스라는뿐만 아니라, 정규 분포, 그것은 아래의 확률지도에서 발표 한 정상 상태의 확률로 알려져들을 수 있지만, 오늘 말할 수 없습니다.
여기에 그림 삽입 설명
  사실, 대부분의 경우, 머리의 현상에 강한 초점을 많은 일들이 있습니다, 푸 아송 분포는 확률 이론의 특성을 사용할 수 있으며,이 지역은 확률 연구의 형태로 묘사된다.
여기에 그림 삽입 설명
여기에 그림 삽입 설명
  상기는 개략도 및 포아송 분포 확률 식이다 $ \ 람다 $ 랜덤 이벤트의 발생의 평균 개수의 단위 시간 (또는 단위 영역), $ E는 $ 자연 상수 2.71828 나타내는 나타낸다 .., K는 사건의 개수이다. 소재지 $ \ 람다 $ 표현은 높은 주파수 데이터의 주파수, 농도 현상의 $ \ 람다 $ 작을수록 분명 머리를 그리워 묘사 할 때주의를 기울이십시오.

지역 분류

  局部性有两种基本的分类, 时间局部性空间局部性 ,按Wikipedia的资料,可以分为以下五类,其实有些就是时间局部性和空间局部性的特殊情况。

时间局部性(Temporal locality):

  如果某个信息这次被访问,那它有可能在不久的未来被多次访问。时间局部性是空间局部性访问地址一样时的一种特殊情况。这种情况下,可以把常用的数据加cache来优化访存。

空间局部性(Spatial locality):

  如果某个位置的信息被访问,那和它相邻的信息也很有可能被访问到。 这个也很好理解,我们大部分情况下代码都是顺序执行,数据也是顺序访问的。

内存局部性(Memory locality):

访问内存时,大概率会访问连续的块,而不是单一的内存地址,其实就是空间局部性在内存上的体现。目前计算机设计中,都是以块/页为单位管理调度存储,其实就是在利用空间局部性来优化性能。

分支局部性(Branch locality)

  这个又被称为顺序局部性,计算机中大部分指令是顺序执行,顺序执行和非顺序执行的比例大致是5:1,即便有if这种选择分支,其实大多数情况下某个分支都是被大概率选中的,于是就有了CPU的分支预测优化。

等距局部性(Equidistant locality)

  等距局部性是指如果某个位置被访问,那和它相邻等距离的连续地址极有可能会被访问到,它位于空间局部性和分支局部性之间。 举个例子,比如多个相同格式的数据数组,你只取其中每个数据的一部分字段,那么他们可能在内存中地址距离是等距的,这个可以通过简单的线性预测就预测是未来访问的位置。

实际应用

  计算机领域关于局部性非常多的利用,有很多你每天都会用到,但可能并没有察觉,另外一些可能离你会稍微远一些,接下来我们举几个例子来深入了解下局部性的应用。

计算机存储层级结构

시간 괴짜
  上图来自极客时间徐文浩的《深入浅出计算机组成原理》,我们以目前常见的普通家用电脑为例 ,分别说下上图各级存储的大小和访问速度,数据来源于https://people.eecs.berkeley.edu/~rcs/research/interactive_latency.html
여기에 그림 삽입 설명
  从最快的L1 Cache到最慢的HDD,其两者的访存时间差距达到了6个数量级,即便是和内存比较,也有几百倍的差距。举个例子,如果CPU在运算是直接从内存中读取指令和数据,执行一条指令0.3ns,然后从内存读下一条指令,等120ns,这样CPU 99%计算时间都会被浪费掉。但就是因为有局部性的存在,每一层都只有少部分数据会被频繁访问,我们可以把这部分数据从底层存储挪到高层存储,可以降低大部分的数据读取时间。
  
  可能有些人好奇,为什么不把L1 缓存做的大点,像内存那么大,直接替代掉内存,不是性能更好吗?虽然是这样,但是L1 Cache单位价格要比内存单位的价格贵好多(大概差200倍),有兴趣可以了解下DRAM和SRAM。
  我们可以通过编写高速缓存友好的代码逻辑来提升我们的代码性能,有两个基本方法 。

  1. 让最常见的情况运行的快,程序大部分的运行实际都花在少了核心函数上,而这些函数把大部分时间都花在少量循环上,把注意力放在这些代码上。
  2. 让每个循环内缓存不命中率最小。比如尽量不要列遍历二维数组。

MemCache

여기에 그림 삽입 설명
  MemCache在大型网站架构中经常看到。DB一般公司都会用mysql,即便是做了分库分表,数据数据库单机的压力还是非常大的,这时候因为局部性的存在,可能很多数据会被频繁访问,这些数据就可以被cache到像redis这种memcache中,当redis查不到数据,再去查db,并写入redis。
  因为redis的水平扩展能力和简单查询能力要比mysql强多了,查起来也快。所以这种架构设计有几个好处:

  1. 加快了数据查询的平均速度。
  2. 大幅度减少DB的压力。

    CDN

      CDN的全称是Content Delivery Network,即内容分发网络(图片来自百度百科) 。CDN常用于大的素材下发,比如图片和视频,你在淘宝上打开一个图片,这个图片其实会就近从CDN机房拉去数据,而不是到阿里的机房拉数据,可以减少阿里机房的出口带宽占用,也可以减少用户加载素材的等待时间。
    여기에 그림 삽입 설명
      CDN在互联网中被大规模使用,像视频、直播网站,电商网站,甚至是12306都在使用,这种设计对公司可以节省带宽成本,对用户可以减少素材加载时间,提升用户体验。看到这,有没有发现,CDN的逻辑和Memcache的使用很类似,你可以直接当他是一个互联网版的cache优化。

    Java JIT

  JIT全称是Just-in-time Compiler,中文名为即时编译器,是一种Java运行时的优化。Java的运行方式和C++不太一样,因为为了实现write once, run anywhere的跨平台需求,Java实现了一套字节码机制,所有的平台都可以执行同样的字节码,执行时有该平台的JVM将字节码实时翻译成该平台的机器码再执行。问题在于字节码每次执行都要翻译一次,会很耗时。
  여기에 그림 삽입 설명
  图片来自郑雨迪Introduction to Graal ,Java 7引入了tiered compilation的概念,综合了C1的高启动性能及C2的高峰值性能。这两个JIT compiler以及interpreter将HotSpot的执行方式划分为五个级别:

  • level 0:interpreter解释执行
  • level 1:C1编译,无profiling
  • level 2:C1编译,仅方法及循环back-edge执行次数的profiling
  • level 3:C1编译,除level 2中的profiling外还包括branch(针对分支跳转字节码)及receiver type(针对成员方法调用或类检测,如checkcast,instnaceof,aastore字节码)的profiling
  • level 4:C2编译

  通常情况下,一个方法先被解释执行(level 0),然后被C1编译(level 3),再然后被得到profile数据的C2编译(level 4)。如果编译对象非常简单,虚拟机认为通过C1编译或通过C2编译并无区别,便会直接由C1编译且不插入profiling代码(level 1)。在C1忙碌的情况下,interpreter会触发profiling,而后方法会直接被C2编译;在C2忙碌的情况下,方法则会先由C1编译并保持较少的profiling(level 2),以获取较高的执行效率(与3级相比高30%)。
  这里将少部分字节码实时编译成机器码的方式,可以提升java的运行效率。可能有人会问,为什么不预先将所有的字节码编译成机器码,执行的时候不是更快更省事吗?首先机器码是和平台强相关的,linux和unix就可能有很大的不同,何况是windows,预编译会让java失去夸平台这种优势。 其次,即时编译可以让jvm拿到更多的运行时数据,根据这些数据可以对字节码做更深层次的优化,这些是C++这种预编译语言做不到的,所以有时候你写出的java代码执行效率会比C++的高。

CopyOnWrite

  CopyOnWrite写时复制,最早应该是源自linux系统,linux中在调用fork() 生成子进程时,子进程应该拥有和父进程一样的指令和数据,可能子进程会修改一些数据,为了避免污染父进程的数据,所以要给子进程单独拷贝一份。出于效率考虑,fork时并不会直接复制,而是等到子进程的各段数据需要写入才会复制一份给子进程,故此得名 写时复制
  在计算机的世界里,读写的分布也是有很大的局部性的,大多数情况下写远大于读, 写时复制 的方式,可以减少大量不必要的复制,提升性能。 另外这种方式也不仅仅是用在linux内核中,java的concurrent包中也提供了CopyOnWriteArrayList CopyOnWriteArraySet。像Spark中的RDD也是用CopyOnWrite来减少不必要的RDD生成。
  

处理

  上面列举了那么多局部性的应用,其实还有很多很多,我只是列举出了几个我所熟知的应用,虽然上面这些例子,我们都利用局部性得到了能效、成本上的提升。但有些时候它也会给我们带来一些不好的体验,更多的时候它其实就是一把双刃剑,我们如何识别局部性,利用它好的一面,避免它坏的一面?

识别

  文章开头也说过,局部性其实就是一种概率的不均等性,所以只要概率不均等就一定存在局部性,因为很多时候这种概率不均太明显了,非常好识别出来,然后我们对大头做相应的优化就行了。但可能有些时候这种概率不均需要做很详细的计算才能发现,最后还得核对成本才能考虑是否值得去做,这种需要具体问题具体分析了。    
  如何识别局部性,很简单,看概率分布曲线,只要不是一条水平的直线,就一定存在局部性。  

利用

  发现局部性之后对我们而言是如何利用好这些局部性,用得好提升性能、节约资源,用不好局部性就会变成阻碍。而且不光是在计算机领域,局部性在非计算机领域也可以利用。
##### 性能优化
  上面列举到的很多应用其实就是通过局部性做一些优化,虽然这些都是别人已经做好的,但是我们也可以参考其设计思路。
  恰巧最近我也在做我们一个java服务的性能优化,利用jstack、jmap这些java自带的分析工具,找出其中最吃cpu的线程,找出最占内存的对象。我发现有个redis数据查询有问题,因为每次需要将一个大字符串解析很多个键值对,中间会产生上千个临时字符串,还需要将字符串parse成long和double。redis数据太多,不可能完全放的内存里,但是这里的key有明显的局部性,大量的查询只会集中在头部的一些key上,我用一个LRU Cache缓存头部数据的解析结果,就可以减少大量的查redis+解析字符串的过程了。
  另外也发现有个代码逻辑,每次请求会被重复执行几千次,耗费大量cpu,这种热点代码,简单几行改动减少了不必要的调用,最终减少了近50%的CPU使用。
  
##### 非计算机领域
  《高能人士的七个习惯》里提到了一种工作方式,将任务划分为重要紧急、不重要但紧急、重要但不紧急、不重要不紧急四种,这种划分方式其实就是按单位时间的重要度排序的,按单位时间的重要度越高收益越大。《The Effective Engineer》里直接用leverage(杠杆率)来衡量每个任务的重要性。这两种方法差不多是类似的,都是优先做高收益率的事情,可以明显提升你的工作效率。
  이만큼 큰 이익, 일을 가치가 있다고 상대적으로 몇 가지 있기 때문에,의 로컬 작업 수익률 결과입니다. 법률 __82의 __의 매우 잘 알려진 규칙이 많은 산업에 많은 지역이, 적용 할 수도있다 XXX에 XXX에서 80 % 내지 20 %를 수익의 80 %는 지역에, 작업 작업의 20 %에서 온다 우리의 계시 "는 항상 20 %의 가장 중요한에 초점을 맞 춥니 다."

기피

  위의 우리 지역으로 성능을 개선하는 방법에 대해 이야기하고있다, 그러나 때때로 우리는 현지 농산물을 방지 할 필요가있다. 예를 들어, 대용량 데이터 작업에 종종 데이터가 왜곡, 지역화 된 데이터 분산에 의해 발생되는 데이터 뜨거운 문제는, 데이터가 우리의 데이터는 종종 매우 긴 시간이 소요되는 컴퓨팅 작업을 주도 왜곡 발생, 데이터는 일부 핫스팟으로 이어질 것입니다 단일 노드 성능 전체 클러스터의 병목하지만, 대부분의 노드가 매우 바쁜이 우리가 피할 필요가 무엇인가.
  데이터가 균일 한 분포에 도달 할 수 있도록 일반적으로, 우리는 전체 데이터를 재 해시 너무 화가 뜨거운 제공된 데이터가 절단 경사 방법을 해결 물론, 일부 비즈니스 로직은, 당신은 무료로 데이터를 방해하는 특정 문제를 분석 할 수있는이 시간을 할 수 없습니다. 빅 데이터 분야의 느낌, 지역은 물론, 당신은 HDFS 작은 단일 노드 파일을 읽을 핫스팟과 같은 다른 수단을 통해 해결해야하는 경우 피할 수없는, 플러스 복사본을 줄임으로써 완화 될 수 있고, 피하려고합니다. 더 본질적 만 핫 스팟을 완화하기 위해 자원을 증가시키기 위해, 현지화 피가 없다, 그것은 또한이 방법 플러스 자원을 탈선 레디 스 성단에 응답을의 microblogging에 있다고한다.
 

참고 자료

  1. 지역의 위키 백과 원리
  2. "컴퓨터 조직 및 설계"데이비드 A.Patterson / 존 L.Hennessy
  3. "평신도의 언어 컴퓨터 구성 원리는"시간이 쑤 웬은 괴짜
  4. "심층 컴퓨터 시스템의 이해"랜달 E.Bryant / 데이비드 O'Hallaron 공 알렉 / 레이 Yingchun (번역)
  5. 인터랙티브 대기 시간
  6. GRAAL 소개 청 유 디

추천

출처www.cnblogs.com/xindoo/p/11303906.html