Graphite Simulator模拟器详解

来源:互联网 发布:淘宝付款默认花呗 编辑:程序博客网 时间:2024/04/27 19:37

  • Graphite模拟器

      Graphite Simulator是由MIT的Carbon研究组开发的一款并行分布式全系统模拟器。设计目标是针对与未来的多核甚至千核,提供高性能的设计和软件开发平台。使用了直接执行、无缝多核和多机分布、可分析性建模、松散同步等技术来提高模拟性能。提供了功能模拟和性能模拟两方面的模型,能够模拟core、NoC、存储子系统包括维护cache一致性的cache结构等。设计模块高度模块化,易于替换和添加不同的体系结构或者进行精确的性能均衡评估。

      Graphite模拟器是一个运行在多核之上的多核模拟器,设计定位与提高多核机器的功能和并行性。但是它也支持在机群服务器上加速单一的模拟任务,即单机模拟运行在机群多核之上。这种功能对应用层和程序员是透明的。线程被自动分布到宿主机的多核之上,而模拟器则表现出所有的线程只运行在单处理器核上。这使得模拟器可在任意数量机器上运行编译后的并行应用程序,而不需要重新编译或配置。

      Graphite设计之初并没有定位于实现cycle精确的数据统计,但是可以使用数据收集模型和一些技术提供精确的性能统计和其他数据统计。来自功能模型中core、network和存储子系统的指令、事件都会经过时序模型进行分析,用来统计数据和更新本地时钟数。本地时钟数是在核之间的消息时间戳来交互和同步的。为了减少同步消息的时间的浪费,Graphite不要求事件严格按照时序进行处理。采用松散同步机制[14]。

 

  • 系统体系结构

      Graphite是一个针对tile级别的多核体系结构的应用程序级模拟器,可以运行在一个或多个宿主机上,每个宿主机可以是单核或多核。图1 为多线程应用程序运行在宿主机群,Graphite能够将应用程序多线程映射到目标系统中的tile上,并且能够将这些线程任务分发到宿主机上的多处理器上。宿主机负责调度和执行这些线程。


1 应用程序-线程-宿主机之间的调用关系

 

      图2展示了Graphite设计模拟的目标系统体系结构。多个目标tile通过片上网络互联,每一个tile包括一个计算core,一个网络switch,一个存储子系统部件。Tiles可以是同构的也可以是异构的。


2 Graphite设计模拟的目标系统体系结构

 

      Graphite采用模块化设计,每个模块都可以被单独替换,并且每个组件都有丰富的接口。模块可以通过运行时参数配置,或者被完全替换成其它模块用于研究。也可以通过替换模块来达到性能和精确度的不同权衡。

图3展示了模拟器的主要组成组件。应用线程通过动态二进制翻译器来解释执行,通过重写指令来生成重要的事件。这些事件会引起traps输入到模拟器终端部件,例如core、memory、network等。终端通过动态二进制翻译器DBT来监听这些事件,包括访存、系统调用、同步信息以及用户级信息。DBT也用来生成指令流驱动core的计算模型。



3 模拟器的主要组成组件

 

     Graphite模拟器终端可以被广泛地分成两个特征集:功能性和时序性。时序模拟模拟目标系统的各方面的特征,功能模拟保证程序结果的正确性。

 

  •  时序特征

     Core model负责模拟流水级内容,memory model负责模拟存储子系统,包括多级cache和DRAM,network model处理路由NoC的传输包并且负责计算传输延时和路由开销。

     模拟器时序模拟通过模块之间的相互联系来确定应用程序中的事件开销。例如,存储器模型通过使用roud trip延时次数来计算访存操作的延时,而core模型依赖访存模型的延时来计算执行存取操作的时间开销。

      Graphite模拟器取得较好的性能的技术之一就是使用松散同步机制。在松散同步机制中,每一个目标tile维护自己的本地时钟,不同tiles之间的同步仅仅发生在应用程序同步事件、用户级消息通信以及线程创建和线程结束。

 

  • 功能特征

      Graphite模拟器能够在多机上直接执行未修改的pthread编程模型的应用程序,为了支持这种功能,Graphite模拟器使用了一些特殊技术来保证程序的正确性。

  • 单地址映射空间

       因为应用程序的线程执行在不同的进程上,并且映射到不同的地址空间,如果允许程序分散的访问宿主机的地址空间会造成功能错误。Graphite模拟提供了处理机制来修改访存操作把应用程序地址空间统一编址,提供给所有的线程并且维护他们之间的数据一致性。

  • 一致的OS接口

     因为应用线程执行在不同宿主机的多线程上,Graphite实现了一个系统接口层来监听和处理所有的应用程序的系统调用,这样可以让应用线程感知到只是运行在单进程上。

  • 线程接口

      Graphite实现了线程接口来监听应用程序线程创建请求,然后将线程分发到多机中运行。线程接口也实现了特定的线程管理和同步功能,其它的操作由单个一致性地址空间来自动处理。

      为了面对这些挑战,模拟器增加了额外的Master Control Program线程以及Local Control Program。每个进程中都有一个LCP,但是整个模拟器只有一个MCP。MCP和LCP能够保证功能正确性,因为它们负责维护同步、系统调用和线程管理的工作。

 

  • 模拟器具体实现

    下面介绍模拟器如何实现高性能的并行离散事件的模拟。

  • Core性能模型

      Core的性能模型单纯的模拟系统时钟功能。它遵循生产者消费者模型:core来消费指令,而其它动态信息是由系统的其它部分产生。大部分的指令使用动态二进制翻译器产生。系统的其它部分也能产生一些伪指令来更新本地时钟。例如,当应用程序使用网络消息API传递消息,网络模型产生“消息接受伪指令”,当一个线程在core上新建后,就是产生一个“新建伪指令”。

      其它的信息需要其它的执行部件去模拟。例如访存操作的演示,分支路线等等,这些都是动态生成的,不包括在指令trace里面。这些信息是由模拟终端或是二进制翻译器产生,被core性能模型使用。这样将功能模型和时序模型分离开模拟,就可以异步执行,互相不打扰,防止引入功能性错误。

       因为性能模拟和功能模型是分开的,这样就提供了极大的灵活性来匹配不同的目标体系结构。目前,Graphite支持顺序core模型和乱序访存系统。存储缓冲,加载部件,分支预测和指令消耗都是可以模拟和配置的。

 

  • 存储系统模型

     Graphite的存储系统同时拥有功能和时序模拟的作用。功能模拟在不同地址空间上为应用程序线程提供抽象的共享地址空间。时序模拟提供cache体系结构的模拟和存储控制器模拟。功能模拟和时序模拟紧耦合,通过网络传输的访存消息既要保证功能正确性又要用于统计时序信息。目前,模拟器支持顺序一致性访存系统,包括全相联和基于有限目录的cahce一致性协议,L1和L2cache私有,每个tile拥有一个访存控制器。

      存储系统的功能模拟提供支持所有的访存操作。动态二进制放一起重写所有的访存向量,对应用程序的访存操作进行重定向。

 

  • 网络模拟

     网络组件提供高层次的tiles之间的消息服务,这些tiles使用共享存储器,使用TCP/IP协议在目标tiles之间通信。

     网络组件维护了几个完全不同的网络模拟模型,通过不同的消息类型启用不同的网络模型。例如,系统消息与应用程序不相关,所以使用不同的网络模型,因此对模拟想结果也不会产生影响。网络模型负责路由消息包和更新时间戳来计算网络延时。

    所以的网络模型使用相同的接口,因此可以随意替换,并且易于开发新的网络模型。目前,Graphite支持无延时的包传输模型以及多个mesh网络模型,区别在于对性能和精确度的不同权衡。

  • 一致的OS接口

     Graphite 实现了系统接口层,可以对系统调用进行监听和处理。

    许多系统调用,例如clone、rt_sigaction,将内存块指针作为输入或输出参数发往内核。Graphite监听这种系统调用然后修改参数来指向正确的数据。系统调用返回后,任何输出数据都会被复制到模拟的地址空间中。

    一些系统调用,例如处理I/O事件,需要特殊的处理来维护目标程序进程的一致性。例如,在多线程应用程序中,线程间的通信有可能依靠文件读写,一个线程调用write系统调用写文件,另一个线程调用read系统调用读文件。在Graphite模拟器中,这些线程也需运行在不同的宿主机线程上,也可能运行在不同的宿主机上,每一个宿主机有自己的文件系统。模拟在处理这些系统调用的时候通过监听并传递给MCP。结果是返回期望的结果给调用线程。

  • 线程构建

     Graphite模拟所面对的一个挑战就是顺利地在分布式模拟上创建线程。其它的编程模型中,例如MPI,强制应用程序用户保证任务的分发和进程的创建。而Graphite模拟器提供了单进程编程模型给用户使用哪个,然后自动将线程分发给不同的主机。

    上面所介绍的功能(线程的分发)可以通过实时配置选项的修改来达到目的,并且不用修改目标代码。

     为了完成这种功能,线程创建调用首先被调用者所监听到,然后传递给MCP来保证统一的线程到tile的映射。MCP选择可用的core并且传递线程创建请求给控制被选的tile的LCP。Tiles和线程之间的映射就可以通过简单的分割来实现。线程合并可以使用相同的方法,利用MCP实现同步。

  • 同步模型

     为了在多机上实现高性能和高可扩展性的目标,Graphite使用松散时钟同步方式来同步各个tiles。所以,Graphite不是cycle精确的。它支持多种不同的同步方式,不同的方式在时钟精度和模拟性能方面偶不同的权衡,分别是:lax synchronization,lax with barrier synchronization 和lax with point-to-point synchronization。Lax synchronization是Graphite模拟器的基础模型。

  • Lax Sync:

     最大限度让模块自由运行,能够提供最好的模拟性能和可扩展性。为了让模拟的时钟能够在合理的范围内,Graphite使用应用程序事件来同步不同模块,其它情况则让线程自由运行。

     所有的模块间的交互通过消息来实现,每个消息携带着发送者的时钟消息。这些时间戳用来在同步事件中更新在同步时钟。单个tile的时钟更新发生在指令完成的时候。出了访存事件的例外,这些事件相对于整个模型老师是相互独立的。然而,访存操作使用消息的round-trip时间来决定延迟。所以他们并不强制来和其它tiles同步。真正的同步发生在一下事件:应用程序同步,例如locks、barrier;通过API接收到消息;创建或合并线程。在所有的情况中,tile的时钟被推进道事件发生的时间点。如果事件在模拟时间之前发生,则不更新事件。

     乱序事件的通用处理方法是忽略模拟时间和进程事件。一种可能的方法是对事件进行重排序,然后以模拟时间的顺序执行事件,但是这样会出现显著的问题。缓冲和重排序事件会导致存储系统死锁,并且难于实现,因为没有全局时钟计数。一种可能性是,模块可以采用乐观事件处理方式,以接收事件的时间来处理事件,如果出现时间乱序则回滚到事件到达时间点,就像BigSim模拟器实现的那样。

    这种复杂的模型,类似于乱序事件处理过程。在cycle精确级的模拟中,packet发送到队列上是需要缓冲处理的。在每个cycle,队头被取出并处理。然而在Graphite模拟器中,packet会被迅速的处理并且携带过去的或是为了的事件戳,所以这种策略在这种情况下不适合。

     相反的是,对于队列的延迟,我们是采用了而一个独立的时钟来维护队列时钟信息。这个时钟代表了队列事件全部处理完成时的时间。另外,队列时钟随着事件处理而递进。

     然而,因为系统中的core之间是松散同步的,所以没有一个全局的时钟的概念。整个模拟器时钟的推进是依赖于消息传递的事件戳,所有模块的时间的权衡值是整个模拟的整体时钟。

 

  • Lax with Barrier Synchronization

     Graphite也支持基于全局的时间量同步栅栏机制,即所有的线程运行到一定的cycle数后barrier一下,等到所有线程到达barrier点之后再一起并发执行。

  •  Lax with Point-to-point Synchronization

     LaxP2P同步方法定位于获取和全局松散同步机制相同的时序精确度但是不降低性能和可扩展性。

      在这种同步机制下,在一段时间内,每个tile随机选取另一个同步对象并与其同步。如果其中一个tile的事件超过预设的时间阈值则使其休眠,等待其他tile“赶”上来。


《原文花了好长时间翻译自:GraphiteA Distributed Parallel Simulator for Multicores   不要随便全篇黏贴复制哦。。。吐舌头 》。





原创粉丝点击