用于管理并行高速缓存层级的指令的制作方法

文档序号:6351191阅读:145来源:国知局

专利名称::用于管理并行高速缓存层级的指令的制作方法
技术领域
:本发明的实施例总体上涉及多线程处理,以及,更具体地,涉及一组能够使应用软件对并行线程处理器中的并行高速缓存层级(cachehierarchy)进行管理的指令。
背景技术
:传统的高速缓存策略技术试图通过确定加载和存储的操作模式,来努力预测应该对哪些数据进行高速缓存和/或清除。然而,在高度多线程并行处理器中,要对模式进行确定则是极端困难的。例如,可以同时执行超过10000个线程,而这使得模式检测是非常困难的。此外,高度多线程并行处理器,诸如图形处理单元(GPU),与诸如CPU(中央处理器)内核的串行处理器相比,其每一个线程仅具有相对较小的高速缓存容量。相应地,本
技术领域
需要的是能够有效地利用多线程并行处理器中有限的高速缓存容量的高速缓存管理技术。
发明内容本发明的实施例提供了使并行多线程应用软件能够协调并发的线程以有效地利用工作集(working-set)容量有限的高速缓存的指令。本发明的实施例提供了针对加载/存储存储器访问指令的显式高速缓存行为修饰符(modifier)。该修饰符可以使程序员和/或编译器能够对以下行为指定高速缓存的优化针对特定的加载/存储存储器指令的易失和非高速缓存行为、工作集行为以及流行为。本发明的一个实施例提供了一种用于管理处理单元中的并行高速缓存层级的方法。该方法包括从调度单元接收指令,其中所述指令包括加载指令或存储指令;确定该指令包括高速缓存操作修饰符,所述修饰符识别用于在所述并行高速缓存层级的一个或多个级别上对与指令相关联的数据进行高速缓存的策略;以及执行所述指令,并且基于所述高速缓存操作修饰符对与所述指令相关联的所述数据进行高速缓存。有利地,本发明的实施例允许程序员和/或编译器来指定在哪个高速缓存级别上对数据进行高速缓存。这使得程序的执行以及数据的访问更加有效率。为了详细地理解本发明的上述特征,对于以上简要说明的发明,可以参照实施例进行更为具体的描述,其中一些实施例示出于附图中。然而,应注意的是,附图中示出的只是本发明的代表性实施例,因此不应被认为是对本发明的范围的限制,本发明可以适用于其他同等有效的实施例。图I为示出了被配置以实现本发明一个或多个方面的计算机系统的框图。图2为根据本发明的一个实施例,用于图I的计算机系统的并行处理子系统的框图。图3A为根据本发明的一个实施例,图2中一个PPU内的GPC的框图。图3B为根据本发明的一个实施例,图2中一个PPU内的分区单元的框图。图3C为根据本发明的一个实施例,图3A中SPM的一部分的框图。图4为根据本发明的一个实施例,图2中的一个或多个PI3U可经配置以实现的图形处理管线的示意图。图5为根据本发明的一个实施例,示出了并行线程处理器中的并行高速缓存层级的示意图。图6为根据本发明一个实施例,用于处理加载存储器访问指令的方法步骤的流程图。图7为根据本发明的一个实施例,用于处理存储存储器访问指令的方法步骤的流程图。具体实施例方式在下面的说明中,将阐述大量的细节以提供对本发明更为彻底的理解。然而,显而易见地是,对于本领域技术人员来说缺少这些细节的一个或多个也可以实施本发明。在其他实例中,没有描述公知的特征,以免对本发明造成混淆。系统概述图I的框图示出被配置为实现本发明一个或多个方面的计算机系统100。计算机系统100包括中央处理器(CPU)102以及经由互连路径进行通信的系统存储器104,该互连路径可包括存储器桥105。存储器桥105,其可能是例如北桥芯片,其经由总线或者其它的通信路径106(例如超传输链路)与I/O(输入/输出)桥107相连。I/O桥107,其例如可能是南桥芯片,从一个或多个用户输入设备108(例如,键盘,鼠标)接收用户输入,并且将该输入经由路径106和存储器桥105转发给CPU102。并行处理子系统112经由总线或者其它的通信路径113(例如,PCIExpress,加速图形端口,或者超传输链路)耦合至存储器桥105;在一个实施例中,并行处理子系统112为图形子系统,其向显示设备110(例如,传统的基于CRT或者IXD的监视器)传送像素。系统磁盘114也连接到I/O桥107。开关116提供了在I/O桥107及其他诸如网络接口卡118的组件与不同的外插卡(add-incard)120和121之间的连接。其它的组件(未明确的示出),包括USB或者其它的端口连接、CD驱动器、DVD驱动器、胶片录制设备等等,也可以连接到I/O桥107。可以使用任何适宜的协议,诸如PCI(外围组件互连)、PCI-Express、AGP(加速图形端口)、超传输或者任何其它的总线或者点对点通信协议来实现图I中将各组件互连的通信路径,并且不同设备之间的连接也可使用现有技术中已知的不同的协议。在一个实施例中,并行处理子系统112结合了被优化用于图形和视频处理的电路,包括例如视频输出电路,并且构成了图形处理单元(GPU)。在另一个实施例中,并行处理子系统112结合了被优化用于通用处理的电路,同时保留了底层(underlying)的计算架构,在这里将对其进行更为详细地描述。在另一实施例中,可将并行处理子系统112与一个或多个其它的系统元件,诸如存储器桥105、CPU102以及I/O桥107集成,来形成片上系统(SoC)。可以理解到在这里所显示的系统是说明性的,并且可对其进行变化和修改。可根据需要修改连接拓扑结构,包括桥的数量和布置、CPU102的数量以及并行处理子系统112的数量。例如,在一些实施例中,系统存储器104直接地,而不是通过桥来连接到CPU102,并且其它的设备经由存储器桥105以及CPU102与系统存储器104进行通信。在其它可供选择的拓扑结构中,并行处理子系统112连接到I/O桥107,或者直接连接到CPU102,而不是连接到存储器桥105。但在其它的实施例中,可将I/O桥107以及存储器桥105集成到单一的芯片中。大量的实施例可以包括两个或更多的CPU102以及两个或更多的并行处理系统112。在这里所显示的具体的组件是可选择的;例如,可支持任何数量的外插卡或者外围设备。在一些实施例中,删除了开关116,并且网络适配器118和外插卡120、121直接连接到I/O桥107。图2示出了根据本发明一个实施例的并行处理子系统112。如同所显示的,并行处理子系统112包括一个或多个并行处理单元(PPU)202,其每一个都耦合到本地并行处理(PP)存储器204。通常,并行处理子系统包括U个PPU,其中U彡I(此处,相似对象的多个实体使用标识该对象的参考数字以及根据需要结合标识该实体的带有括号的数字来表示)。可以使用一个或多个诸如可编程处理器、专用集成电路(ASIC)或者存储器器件的集成电路设备来实现,或者以任何其它技术上可行的方式来实现。再次参考图1,在一些实施例中,并行处理子系统112中的一些或者所有的PPU202,都是具有渲染管线的图形处理器,可以被配置为执行与下述各项相关的各种任务从图形数据中生成像素数据,所述图形数据是由CPU102和/或系统存储器104经由存储器桥105以及总线113所提供的;与本地并行处理存储器204(其能被作为包括了例如传统帧缓冲区的图形存储器来使用)交互来存储并更新像素数据;将像素数据输送到显示设备110,等等。在一些实施例中,并行处理子系统112可以包括一个或多个作为图形处理器来操作的PPU202,以及一个或多个被用于通用计算的其他PPU202。PI3U可以是相同的或者是不同的,并且每个PPU可具有其自己专用的并行处理存储器装置或者非专用的并行处理存储器装置。一个或多个PPU202可以向显示设备110输出数据,或者每一个PPU202都可以向一个或多个显示设备110输出数据。操作时,CPU102是计算机系统100的主处理器,其控制并且协调其他系统组件的操作。具体地,CPU102发出控制PPU202操作的命令。在一些实施例中,CPU102对于每一个PPU202都将命令流写入到入栈缓冲区(pushbuffer)中(未明确地在图I或者图2中示出),该入栈缓冲区可位于系统存储器104、并行处理存储器204、或者可为CPU102和PPU202访问的另外的存储位置中。PPU202从入栈缓冲区中读取命令流,然后相对于CPU102的操作异步地执行命令。现在返回参考图2,每一个PPU202都包括1/0(输入/输出)单元205,该单元经由通信路径113与计算机系统100其余的部分相互通信,该通信路径113连接到存储器桥105(或者在另一个替代实施例中,直接连接到CPU102)。PPU202与计算机系统100其余部分的连接也可以改变。在一些实施例中,可将并行处理子系统112实现为外插卡,该卡可以被插入到计算机系统100的扩展槽中。在其它的实施例中,可以将PPU202与诸如存储器桥105或I/O桥107的总线桥一起集成到单一芯片上。但在其它的实施例中,可将PPU202的某些或者所有的元件与CPU102一起集成到单个芯片上。在一个实施例中,通信路径113是PCI-EXPRESS链路,其中对于每个PPU202都分配了专用通道(lane),如同现有技术中所已知的。也可以使用其它的通信路径。I/O单元205生成用于在通信路径113上传输的数据包(或者其它的信号),以及从通信路径113上接收所有输入进来的数据包(或者其它的信号),将输入的数据包引导到PPU202的适当的组件。例如,可将与处理任务相关的命令引导到主机接口206,而可将与存储器操作相关的命令(例如,对并行处理存储器204的读或者写)引导到存储器交叉开关单元210。主机接口206读取每个入栈缓冲区并且将由入栈缓冲区指定的工作输出给前端212。每一个PPU202都有利地实现了高度的并行处理构架。如同所详细显示地,PPU202(0)包括了处理集群阵列230,该处理集群阵列230包括C个通用处理集群(GPC)208,其中OI。每个GPC208都能够并发地执行大量的(例如数百或者数千个)线程,其中每个线程都是程序的实例。在不同的应用程序中,不同的GPC208可被分配用于处理不同类型的程序或者用于执行不同类型的计算。例如,在图形应用程序中,第一组GPC208可被分配用于执行曲面细分(tessellation)操作以及用于对曲面片生成基元拓扑,并且第二组GPC208可被分配用于执行曲面细分着色以对于基元拓扑的曲面片参数进行评价并确定顶点位置及每个顶点的其他属性。GPC208的分配可依据每个类型的程序或计算产生的工作量而不同。GPC208经由工作分布单元200接收所要执行的处理任务,工作分布单元200从前端单元212接收定义处理任务的命令。处理任务包括将要处理的数据索引,例如表面(曲面片)数据、基元数据、顶点数据和/或像素数据,以及定义了如何对该数据进行处理(例如,将要执行什么程序)的状态参数和命令。可将工作分布单元200配置为获取与任务相对应的索引,或者工作分布单元200可以从前端212接收索引。前端212确保,在由入栈缓冲区所指定的处理开始之前,GPC208被配置成为有效的状态。当PPU202用于图形处理时,例如,将对于每个曲面片的处理工作量分成近似相等规模的任务,以使得可以将曲面细分处理分布给多个GPC208。可将工作分布单元200配置为以能够为多个GPC208提供任务进行处理的频率来生成任务。相反地,在传统的系统中,典型地是由单一的处理引擎来执行处理,而同时其他处理引擎则是保持空闲,在开始它们的处理任务之前等待单个的处理引擎完成其任务。在本发明的一些实施例中,GPC208的各部分被配置为执行不同类型的处理。例如,第一部分可被配置为执行顶点着色(vertexshading)和拓扑生成,第二部分可被配置为执行细分曲面和几何着色,第三部分可被配置为在屏幕空间中执行像素着色以生成渲染后的图像。由GPC208生成的中间数据可被存储在缓冲区中,以允许在GPC208之间对该中间数据进行传输,以用于进一步的处理。存储器接口214包括D个分区单元215,其每一个都直接地耦合到并行处理存储器204的一部分,其中DSI。如同所显示的,分区单元215的数量通常都等于DRAM220的数量。在其它的实施例中,分区单元215的数量可以不等于存储设备的数量。本领域技术人员将会理解DRAM220可被替换为其它适宜的存储设备并且可以是通常的常规设计。因此省略了详细的说明。可跨DRAM220来存储渲染对象,例如帧缓冲器或者纹理映射,允许分区单元215并行地写入每个渲染对象的一部分,以有效地使用并行处理存储器204的可用带宽。任何一个GPC208都可以对将要写入到并行处理存储器204中任何一个DRAM220的数据进行处理。交叉开关单元210被配置为将每个GPC208的输出路由给任一分区单元215的输入或者路由至另一个GPC208,用于进一步的处理。GPC208与存储器接口214通过交叉开关单元210进行通信,以对不同的外部储存器设备进行读取或写入。在一个实施例中,交叉开关单元210具有到存储器接口214的连接以与I/O单元205进行通信,以及到本地并行处理存储器204的连接,从而使在不同的GPC208之中的处理内核能够与系统存储器104或者其它的对于PPU202来说非本地的存储器进行通信。在图2所显示的实施例中,交叉开关单元210直接与I/O单元205相连。交叉开关单元210可以使用虚拟信道,以分离GPC208和分区单元215之间的业务流。在另一方面,GPC208可以被编程用来执行与各式各样的应用程序相关的处理任务,包括但不限于,线性和非线性数据变换、视频和/或音频数据的过滤、建模操作(例如,应用物理定律来确定对象位置、速率及其他属性)、图像渲染操作(例如,细分曲面着色、顶点着色、几何着色和/或像素着色程序)等等。PPU202可以将来自系统存储器104和/或本地并行处理存储器204的数据传送给内部的(片上)存储器,处理该数据,并且将结果数据写回到系统存储器104和/或本地并行处理存储器204,其中这样的数据可以由其它的系统组件访问,包括CPU102或者另一个并行处理子系统112。PPU202可拥有任何容量(amount)的本地并行处理存储器204,包括不设置本地存储器,并且可以任何组合形式来使用本地存储器和系统存储器。例如,在统一(unified)存储器架构(UMA)实施例中,PI3U202可以是图形处理器。在这样的实施例中,将几乎没有或者没有提供专用的图形(并行处理)存储器,并且PPU202将独占地或者是几乎独占地使用系统存储器。在UMA实施例中,可将PPU202集成到桥式芯片或者处理器芯片中,或者作为具有高速链路(例如,PCI-EXPRESS)的分立芯片加以提供,该高速链路经由桥式芯片或者其它的通信方式将PPU202连接到系统存储器。如上所述,并行处理子系统112中可包括许任意数量的PPU202。例如,多个PPU202可以被设置在单个外插卡上,或者多个外插卡可以连接到通信路径113,或者PPU202中的一个或多个可以被集成到桥式芯片中。多PPU系统中的PPU202可以是彼此相同或者不同的。例如,不同的PPU202可能具有不同数量的处理内核、不同容量的本地并行处理存储器等等。在具有多个PPU202时,可以并行地进行操作这些PPU,以高于采用单个PPU202可能达到的吞吐量来对数据进行处理。可以用各式各样的配置和形式因素来实现包含一个或多个PPU202的系统,包括桌上型电脑、膝上型电脑、或者手持个人电脑、服务器、工作站、游戏控制台、嵌入式系统等等,。处理集群阵列(ProcessingClusterArray)概述图3A是根据本发明一个实施例的、图2的一个PPU202中GPC208的框图。每个GPC208可被配置为并行地执行大量的线程,其中术语“线程”指的是对一组特定的输入数据所执行的特定程序的实例。在一些实施例中,采用单指令多数据(SIMD)指令发送技术来支持大量线程的并行执行,而不必提供多个独立的指令单元。在其它的实施例中,采用单指令多线程(SMT)技术,使用被配置为发送指令到每一个GPC208内一组处理引擎的公共指令单元,来支持大量通常同步化线程的并行执行。与所有的处理引擎一般都执行相同指令的SMD执行方式不同,SIMT执行通过给定线程程序允许不同的线程更加容易地跟踪离散型的执行路径。本领域技术人员将会理解到SMD处理机制相当于SMT处理机制的功能子集。经由管线管理器305可方便地控制GPC208的操作,该管线管理器305向流多处理器(SPM)310分布处理任务。管线管理器305也可被配置为,通过为SPM310所输出的经处理数据指定目的地,来控制工作分布交叉开关330。在一个实施例中,每个GPC208都包括M个SPM310,其中M彡I,每个SPM310都被配置为处理一个或多个线程组。而且,每个SPM310有利地包括相同的一组可被管线化的功能执行单元(例如,算术逻辑单元,以及加载-存储单元,如在图3C中所示的Exec单元302和LSU303),允许在前一个指令结束之前发送新的指令,如现有技术中所知的。可提、供功能执行单元的任何组合。在一个实施例中,功能单元支持多种运算,包括整数和浮点算法(例如,加法和乘法)、比较运算、布尔运算(AND和、OR或、XOR异或)、位移以及不同代数函数的计算(例如,平面内插、三角、指数、以及对数函数,等等);并且相同功能单元硬件可均衡地用于(beleveragedto)执行不同运算。传送到特定GPC208的指令序列形成线程,如之前本文所定义的,并且在此将跨SPM310中并行处理引擎(没有示出)所并发执行的一定数量的线程的集合称为“卷绕包(warp)”或“线程组”。如同在此所使用的,“线程组”指的是针对不同的输入数据,并发执行相同程序的一组线程,其中该组中有一个线程被分配给SPM310中的不同的处理引擎。线程组可以包括比SPM310中的处理引擎数量更少的线程,而在这样情况下,在该线程组正在被执行的周期内,一些处理引擎将会处于空闲状态。线程组同样可以包括比SPM310中的处理引擎数量更多的线程,而在这样情况下,处理将在连续的时钟脉冲周期上发生。因为每个SPM310可以并发支持多达G个线程组,于是在任何给定的时间在GPC208中可以允许执行多达G*M个线程组。此外,在SPM310中可有多个相关的线程组同时处于激活状态(处于执行的不同阶段)。在此将该线程组的集合称为“协作线程阵列”(“CTA”)或者“线程阵列”。特定CTA的大小等于m*k,其中k是在线程组中并发执行线程的数量,并且k一般是SPM310中并行处理引擎数量的整数倍数,并且m是SPM310中同时处于激活状态的线程组的数量。CTA的大小通常是由程序员以及CTA可用的硬件资源的诸如存储器或者寄存器的容量来决定的。每个SPM310都包括LI高速缓存(没有示出)或者使用SPM310之外的相应的LI高速缓存中用于执行加载和存储操作的空间。而且每个SPM310都可以访问分区单元215内的L2高速缓存,该高速缓存由所有的GPC208所共享,并且可用于在线程之间传送数据。最后,SPM310还可以访问片外“全局”存储器,其可包括例如并行处理存储器204和/或系统存储器104。将要理解到的是PPU202之外的任何存储器都可作为全局存储器来使用。此外,可将LI.5高速缓存335包括在GPC208之内,其被配置为据SPM310的请求经由存储器接口214来接收并且保持从存储器中所获取的数据,其包括指令、一致性(uniform)数据以及常数数据,并且将所请求的数据提供给SPM310。在GPC208中具有多个SPM310的实施例有利于共享被缓存在LI.5高速缓存335中的共同指令和数据。每个GPC208都可包括存储器管理单元(MMU)328,其被配置为将虚拟地址映射为物理地址。在其他的实施例中,MMU328可以位于存储器接口214内。MMU328包括一组页表项目(PTE)以及可选地包括高速缓存线索引(cachelineindex),该组PTE被用于将虚拟地址映射到像素块(tile)的物理地址。MMU328可包括地址转换后备缓冲区(TLB)或者高速缓存,其可以位于多处理器SPM310或者LI高速缓存或者GPC208之中。对物理地址进行处理,来分散表面数据访问位置,以允许在分区单元之间交错的高效请求。高速缓存线索引可用来确定对于高速缓存线的请求是否命中或失败。在图形以及计算应用程序中,可对GPC208进行配置使得每个SPM310都耦合到纹理单元315,以执行纹理映射操作,例如确定纹理采样位置、读取纹理数据以及过滤纹理数据。根据需要,从内部的纹理LI高速缓存(没有示出)中读取纹理数据,或者在一些实施例中从SPM310中的LI高速缓存读取纹理数据,以及从L2高速缓存、并行处理存储器204或者系统存储器104中取得纹理数据。每个SPM310都向工作分布交叉开关330输出处理后的任务,以便向另一个GPC208提供该处理后的任务用于进一步的处理,或者经由交叉开关单元210将该处理后的任务存入L2高速缓存、并行处理存储器204或者系统存储器104中。PreROP(pre-rasteroperations,预光栅操作)325被配置为从SPM310接收数据,将数据引向分区单元215中的ROP单元,并且执行对色彩混合的优化、组织像素色彩数据、以及执行地址转换。应该予以理解的是,在此所描述的内核架构是说明性的而且是可变化以及修改的。可在GPC208中包括任何数量的处理单元,例如SPM310或者纹理单元315、PreROP325。此外,虽然仅显示了一个GPC208,但是PPU202可包括任何数量的GPC208,其最好在功能上彼此相类似,以便执行行为将不会依赖于是哪个GPC208接收了特定的处理任务。此外,每个GPC208都最好使用单独且不同的处理单元、LI高速缓存等,独立于其它的GPC208进行操作。图3B是根据本发明的一个实施例的、在图2中的一个PPU202之内的分区单元215的框图。如所显示的,分区单元215包括L2高速缓存350、帧缓冲区(FB)DRAM接口355以及光栅操作单元(R0P)360。L2高速缓存350是读/写高速缓存,其被配置为对从交叉开关单元210和ROP360所接收的操作进行加载和存储。由L2高速缓存350将读取失败以及紧急回写请求输出给FBDRAM接口355以用于处理。还将脏的更新(Dirtyupdate)发送给FB355用于伺机处理。FB355与DRAM220直接对接,输出读和写请求并且接收从DRAM220读取的数据。在图形应用程序中,ROP360是处理单元,其执行光栅操作并且输出作为处理后图形数据的像素数据用于在图形存储器中存储,其中光栅操作例如模板(stencil)、z测试、混合等等。在本发明的一些实施例中,ROP360被包括在每个GPC208而非分区单元215中,并且将像素读和写请求而不是像素片段数据通过交叉开关单元210进行传输。可在显示设备110上显示处理后的图形数据,或者对该图形数据进行路由以用于由CPU102或又并行处理子系统112中的一个处理实体来进行进一步的处理。每个分区单元215都包括ROP360以便分布光栅操作的处理。在一些实施例中,可将ROP360配置为对被写入存储器中z数据或者色彩数据进行压缩,以及对从存储器中读取出来的z数据或者色彩数据进行解压缩。本领域技术人员将会理解在图1、2、3A和3B中描述的架构不以任何方式对本发明的范围进行限制,而且在此教导的技术可在任何被适当设置的处理单元上实现,该处理单元包括但并非限制,一个或多个CPU、一个或多个多内核CPU、一个或多个PPU202、一个或多个GPC208、一个或多个图形或者特殊用途处理单元等等,均不脱离本发明的范围。在本发明的实施例中,使用PPU202或者其它计算系统的处理器来采用线程阵列执行通用计算是可取的。在线程阵列中的每个线程都分配有唯一的线程标识符(“线程ID”),线程在其执行期间可对该线程标识符进行访问。线程ID可被定义为一维的或多维的数值,控制线程处理行为各个方面。例如,线程ID可能被用来确定线程将对输入数据集的哪个部分进行处理,和/或确定线程将要生成或者写入输出数据集哪个部分。每一线程的指令序列都可以包括至少一个指令,该指令定义了代表性线程和线程阵列中一个或多个其它线程之间的协作行为。例如,每一线程的指令序列可能包括下列指令在序列中的特定点处挂起代表性线程的操作的执行直到一个或多个其他线程到达该特定点时为止的指令,指示代表性线程将数据存储在一个或多个其他线程有权访问的共享存储器中的指令,,指示代表性线程自动读取和更新存储在共享存储器中的数据的指令,一个或多个其他线程基于其线程ID有权访问所述共享存储器,等等。CTA程序还可以包括计算将从中读取数据的共享存储器中的地址的指令,其中地址为线程ID的函数。通过定义适宜的函数并提供同步技术,可以用可预测的方式,由CTA的一个线程将数据写入到共享存储器中给定的位置,以及由同一个CTA中不同的线程从该位置读取出数据。从而,线程之间任何期望模式的数据共享都可以得到支持,并且在CTA中任何的线程都可以与同一CTA中的任何其他线程共享数据。如果需要的话,可由CTA程序来决定在CTA的线程之中数据共享的程度;如此,可以理解到在特定的使用了CTA的应用程序中,CTA的线程彼此之间可能或者可能不实际地共享数据,这取决于CTA程序,并且在此对术语“CTA”和“线程阵列”以相同的含义进行使用。图3C是根据本发明的一个实施例,图3A中SPM310的框图。SPM310包括指令LI高速缓存370,其被配置为经由LI.5高速缓存335从存储器接收指令和常数。warp调度器和指令单元312从指令LI高速缓存器370接收指令和常数,并且根据该指令和常数对本地寄存器文件304和SPM310功能单元进行控制。SPM310功能单元包括N个exec(执行或者处理)单元302和P个加载-存储单元(LSU)303。SPM310提供了具有不同访问级别(level)的片上(内部的)数据存储。专用寄存器(没有显示)对于LSU303来说是可读取的而不是可写入的,并且其用于存储定义了每个CTA线程“位置”的参数。在一个实施例中,专用寄存器对于每个CTA线程(或者对于SPM310中每个exec单元302)都包括一个存储线程ID的寄存器;每个线程ID寄存器仅可由一个相应的exec单元302进行访问。专用寄存器还可包括辅助寄存器,其可由所有的CTA线程(或者由所有的LSU303)进行读取,该辅助寄存器存储了CTA标识符、CTA维度(dimension)、CTA所属的栅格(grid)的维度以及CTA所属的栅格的标识符。在初始化期间响应于经由前端212从设备驱动器103接收的命令,来对专用寄存器进行写操作,并且该专用寄存器在CTA执行期间不会变化。参数存储器(未被显示)存储了运行时(runtime)参数(常数),可以由任何的CTA线程(或者任何的LSU303)对该参数进行读取而非写入。在一个实施例中,设备驱动器103在引导SPM310开始对使用这些参数的CTA的执行之前,将参数提供给参数存储器。在任何CTA(或者SPM310中的任何exec单元302)中的任何CTA线程可以通过存储器接口214来访问全局存储器。可在LI高速缓存320中存储全局存储器的一部分。本地寄存器文件304被每个CTA线程用作临时空间(scratchspace);每个寄存器都被分配用于一个线程的排他性使用,并且任何本地寄存器文件304中的数据仅对于该寄存器被分配给的CTA线程可访问。可以将本地寄存器文件304实现为在物理上或者逻辑上被划分成P个通道的寄存器文件,每个通道都具有一定数量的条目(entry)(其中每个条目都可能存储,例如32比特的字符)。对N个exec单元302和P个加载-存储单元LSU303中的每一个都分配一个通道,并且可以使用用于执行同一个程序的不同线程的数据来填充不同通道中的相应条目,以有助于SIMD的执行。可以将通道的不同部分分配给G个并发线程组中不同的线程组,以便本地寄存器文件304中给定的条目仅对特定的线程是可访问的。在一个实施例中,在本地寄存器文件304中的某些条目被保留用于存储线程标识符,其实现了一个专用寄存器。共享存储器306对于所有的CTA线程(在单一的CTA之内)都是可访问的;共享存储器306中的任何位置对于在同一个CTA中(或者对于SPM310中的任何处理引擎)的任何CTA线程来说都是可访问的。共享存储器306可以被实现为具有互连的共享寄存器文件或者共享片上高速缓存存储器,该互连允许任何处理引擎从共享存储器中的任何位置读取或写入。在其它的实施例中,共享状态空间可以映射到片外(off-chip)存储器的每个CTA区域,并且可以在LI高速缓存320中进行高速缓存。可将参数存储器实现为在实现了共享存储器306的同一个共享寄存器文件或者共享高速缓存存储器中的指定部分,或者LSU303仅能进行只读访问的单独的共享寄存器文件或片上高速缓存存储器。在一个实施例中,也可以将实现了参数存储器的区域用于存储CTAID和栅格ID,以及CTA维度和栅格的维度,由此实现了部分的专用寄存器。SPM310中的每个LSU303都耦合到统一地址映射单元352,该统一地址映射单元将在统一的存储器空间中所指定的为加载和存储指令而提供的地址转换为每个不同存储器空间中的地址。从而,指令可用来访问任何由统一的存储器空间中的地址所指定的本地的、共享的、或者全局的存储器空间。每个SPM310中的LI高速缓存320都可用于对私有的每个线程的本地数据以及每个应用程序的全局数据进行高速缓存。在一些实施例中,可在LI高速缓存320中对每个CTA的共享数据进行高速缓存。LSU303经由存储器和高速缓存的互连380耦合到一致性LI高速缓存375、共享存储器306以及LI高速缓存320。一致性LI高速缓存375被配置为经由LI.5高速缓存335从存储器接收只读数据和常数。图4是根据本发明的一个实施例的图形处理管线400的示意图,可由图2中的一个或多个PPU202配置实现。例如,一个SPM310可被配置为执行顶点处理单元415的功能、几何处理单元425以及片段处理单元460中的一个或多个的功能。还可以由GPC208中的其它处理引擎以及相应的分区单元215来执行数据汇编器410、基元汇编器420、光栅化器455以及光栅操作单元465的功能。另一方面,可使用针对于一个或多个功能的专用处理单元来实现图形处理管线400。数据汇编器410处理单元为高阶表面、基元等等采集顶点数据,并且向顶点处理单元415输出包括了顶点属性的顶点数据。顶点处理单元415为可编程执行单元,其被配置为执行顶点着色程序,从而根据顶点着色程序的指定来光照(lighting)和变换(transforming)顶点数据。例如,可对顶点处理单元415进行编程以将顶点数据从对基于对象的坐标表示(对象空间)变换到诸如世界空间或者规格化设备坐标(NDC)空间的替代基础坐标系统。顶点处理单元415可以通过数据汇编器410读取存储在LI高速缓存320、并行处理存储器204或者系统存储器104中的数据来供顶点数据处理之用。基元汇编器420从顶点处理单元415接收顶点属性,根据需要读取所存储的顶点属性,并且构建图形基元用于由几何处理单元425进行处理。图形基元包括三角形、线段、点等等。几何处理单元425是可编程执行单元,其被配置为执行几何着色程序,依据几何着色程序的指定对从基元汇编器420接收的图形基元进行变换。例如,可对几何处理单元425进行编程,以将图形基元细分成为一个或多个新的图形基元和计算参数,例如平面方程系数,其用于对新的图形基元进行光栅化。在一些实施例中,几何处理单元425也可以添加或者删除几何流中的元素。几何处理单元425向视图缩放、剔除(cull)以及裁剪(clip)单元450输出指定新的图形基元的参数和顶点。几何处理单元425可以读取存储在并行处理存储器204或者系统存储器104中的数据用于在处理几何数据中使用。视图缩放、剔除以及裁剪单元450执行裁剪、剔除以及视图缩放,并且将处理后的图形基元输出到光栅化器455。光栅化器455对新的图形基元进行扫描转换并且将片段和覆盖(coverage)数据输出给片段处理单元460。此外,可将光栅化器455配置为执行z剔除及其他基于z的最佳化。片段处理单元460是可编程执行单元,其被配置为执行片段着色程序,依据片段着色程序的指定,来对从光栅化器455接收的片段进行变换。例如,可对片段处理单元460编程以执行例如透视校正、纹理映射、着色、混合等诸如此类的操作,以生成输出到光栅操作单元465的着色后的片段。片段处理单元460可以读取存储在并行处理存储器204或者系统存储器104中的数据用于在处理片段数据中使用。取决于所编程的采样率,可在像素、样本或者其它粒度上对片段进行着色。光栅操作单元465是处理单元,其执行模板(stencil)、z测试、混合等诸如此类的光栅操作并且输出像素数据作为处理后的图形数据用于存储在图形存储器中的。可将处理后的图形数据存储在图形存储器,例如并行处理存储器204和/或系统存储器104中,以用于在显示设备110上进行显示,或者用于进一步的由CPU102或并行处理子系统112进行处理。在本发明的一些实施例中,可将光栅操作单元465配置为对写入到存储器中的z数据或者色彩数据进行压缩,以及对从存储器中读取出来的z数据或者色彩数据进行解压缩。虽然结合图1、2、3A、3B和3C中的系统对方法步骤进行了描述,但是本领域技术人员将理解到任何配置为以任意顺序执行该方法步骤的系统都在本发明的范围之内。用于管理并行高速缓存层级的指令图5是根据本发明一个实施例的示意图,示出了在并行线程处理器中的并行高速缓存层级。如所显示的,PPU502包括一个或多个SPM510。PPU502耦合到PPU存储器526,该PPU存储器526可以包括DRAM。PPU502也耦合到桥506。桥506耦合到CPU504和系统存储器508。在一种实现方式中,PI3U502经由PCI-Express链路和桥506耦合到CPU504和系统存储器508。如图5所示,每个SPM510均包括指令LI高速缓存512、常数LI高速缓存514、数据LI高速缓存516和/或一致性LI高速缓存518。PPU也包括耦合到每个SPM510的LI.5高速缓存520。L2高速缓存互连耦合到每个SPM510、LI.5高速缓存520和L2高速缓存524中。L2高速缓存524耦合到PPU存储器526。在一个实施例中,每个PPU502都相当于图2中所显示的PPU202,并且每个SPM510都相当于在图3C中所显示的SPM310。例如,如同在图3C中所显示的,指令LI高速缓存512相当于指令LI高速缓存370,数据LI高速缓存516相当于LI高速缓存320,并且一致性LI高速缓存518相当于一致性LI高速缓存375。LI.5高速缓存520可以相当于在图3A中所显示的LI.5高速缓存335。L2高速缓存524可以相当于如在图3B中所显示的L2高速缓存350。在图5所举例说明的示意图中,仅仅显示了并行线程处理器架构中并行高速缓存层级的一种实现方式,具有被称为流多处理器(SPM)510的数量可扩展的线程处理器。在一个实施例中,warp调度器和指令单元312也被包括在SPM510中,从并行线程向并行执行单元302和并行加载-存储单元303提供指令,如同在图3C中所描述的。在图5所示的实施例中,每个SPM510都包括多个不同的LI高速缓存L1指令高速缓存512、L1常数高速缓存514、L1数据高速缓存516以及一致性数据LI高速缓存518。SPM510和LI高速缓存经由高速缓存互连网络522来共享统一的L2高速缓存524。在一些实施例中,在LI高速缓存和L2高速缓存之间提供了辅助的高速缓存层,即,LI.5高速缓存520。L2高速缓存524访问PPUDRAM存储器526,经由PCIe接口来访问系统存储器508,以及可选地,经由PCIe接口访问辅助的对等设备存储器。对等(peer)设备存储器的实例是与附属于同一PCIe网络的另一个PPU的DRAM存储器。SPM加载-存储单元(LSU)303(在图3C中所显示的)执行存储器访问指令,包括如下所列的加载、存储和高速缓存控制指令Id{.cop}.szrd,[ra+offset];//从存储器加载ldu.szrd,[ra+offset];//经由一致性高速缓存加载st{.cop}.sz[ra+offset],rb;//存储到存储器中cctl.cache.op{rd,}[ra+offset];//高速缓存控制操作如同在此所使用的,术语“加载(load)”描述了从存储器读取并返回值的指令,而术语“存储(store)”描述了将值写到存储器中的指令。一些指令,例如原子和锁操作,会修改存储器并返回值,并且应该被看作兼备加载和存储的语义,因此,同时遵循加载和存储的规则。下面对加载指令和存储指令“高速缓存操作”(.cop)加以描述。下面还对高速缓存控制指令cctl加以描述。用于加载和存储指令的高速缓存操作加载和存储指令在由地址操作数所指定的有效地址上对存储器进行读取或者写入。.sz后缀指定了将要读取或者写入存储器中的字节大小,并且SPM指令集架构(ISA)可以支持1、2、4-、8和16个字节的大小用于加载/存储指令。有效存储器地址是寄存器ra加上立即数offset(偏移)的字节总和。ld{.cop}.szrd,[ra+offset]-J/从存储器加载rdst{.cop}.sz[ra+offset],rb-J/将rb存储到存储器中在一些实施例中,SPM510使用32比特的地址,以及使用指定有后缀.e的64比特的扩充地址,实现了两个版本的存储器存取指令(即,指令Id.e和st.e)。加载指令高速缓存操作Id.cop加载指令具有可选的由.cop所指定的高速缓存操作,编译程序和/或程序员可以用来优化对全局存储器空间和对本地每个线程的专用存储器空间进行访问的高速缓存使用。依赖于由系统软件和PPU存储器管理单元(MMU)页表(pagetable)所提供的虚拟地址到物理地址的映射,全局的和本地的存储器访问可以映射到PPU(DRAM)存储器526、系统存储器508和PCIe设备存储器。在一种实现方案中,对共享存储器RAM的访问忽略了高速缓存操作,但是对共享存储器空间进行高速缓存的实现方案则可以使用高速缓存操作。关于加载指令Id{.cop}和Id.e{.cop}的可选高速缓存操作是.ca在所有级别(level)上进行高速缓存,有可能被再次访问(缺省值).eg在全局级别上进行高速缓存(在L2和之下的级别,非LI上进行高速缓存).CS高速缓存流,有可能被访问一次,绕过高速缓存或者提前回收(evict).Iu最后使用如果地址是每个线程的本地地址,并且高速缓存线被完全地覆盖(由warp的线程来访问在高速缓存线中的所有数据),则加载然后使该线无效并且取消任何待定的脏回写,否则加载并且将高速缓存线标记为回收优先。·cop的编码与.CS的相同。.Cv如果地址是在系统存储器中,则以易失(volatile)的方式进行高速缓存;认为高速缓存的系统存储器线失去时效时,再次获取。缺省的Id指令高速缓存操作是Id.ca,其在所有级别(LI和L2)上用正常的回收策略来分配高速缓存线。在一个实施例中,当应用程序希望多次访问同一个高速缓存线,并且希望其访问命中在LI高速缓存的工作集中的时候,应用程序可以使用这个指令。全局数据在L2高速缓存级别中是连贯的(coherent),但是在一种实现方案中,在每个SPM中的多个LI高速缓存对于全局数据来说并非彼此连贯。如果一个线程经由一个LI高速缓存存储到全局存储器,并且在不同的SPM中的第二个线程使用Id.ca经由第二个LI高速缓存来加载那个地址,那么第二个线程可能得到的是失去时效的LI高速缓存数据,而不是由第一个线程所存储的数据。由此,驱动器将会使全局LI高速缓存线在并行线程的从属栅格之间无效。如同下面所要详细描述的,程序还可以使用高速缓存控制指令cctl来使LI高速缓存线无效。随后由第二个栅格程序正确地获取由第一个栅格程序所进行的存储,该第二个栅格程序发布被高速缓存在LI高速缓存中的缺省的Id.ca加载。这个指令支持可选的实现方案,其提供了在多个LI高速缓存中的高速缓存连贯性。可供选择地,程序可以利用如下所述的Id.eg加载高速缓存全局操作,来绕过LI高速缓存级别,以避免读取失去时效的LI数据。在一个实施例中,指令Id.Cg仅用于全局的高速缓存加载,绕过LI高速缓存并且仅在全局的(L2高速缓存)级别上进行高速缓存。当应用程序希望读取一次地址时,并且在相对较小的LI高速缓存中减少工作集的扰动的时候,其可以使用这个指令。这个指令使不同SPM中的线程之间能够通信。该Id.cs加载高速缓存流操作,使用回收-优先策略在LI和L2中分配全局线,以限制由临时性流数据导致的高速缓存污染,该临时性流数据可被访问一次或两次。在另一个实施例中,流数据可以经由小的流高速缓存或者与每个高速缓存相邻的先入先出(FIFO)来绕过LI和L2高速缓存,以便流数据不会干扰LI或者L2的工作集。当将Id.cs用于本地窗口地址时,其执行如下所述的Id.Iu操作。该Id.Iu加载最后使用操作,当被应用于本地每线程私有的地址的时候,如果本地LI高速缓存线被完全覆盖(该高速缓存线中的所有数据被warp的线程读取),则该操作在加载之后将该线无效(即,如果自在先的存储起该线是脏的,则丢弃和取消该线的任何待定的脏的回写)。当要恢复溢出的寄存器以及弹出功能堆栈帧时,编译器和/或程序员可以使用Id.Iu以避免对不会被再次使用的线进行不必要的回写。Id.Iu指令具有与Id.cs相同的高速缓存操作.cop编码,并且Id.Iu指令执行在全局地址上的加载高速缓存流操作。该Id.CV加载高速缓存易失操作被应用于全局的系统存储器地址,其使匹配的L2线无效(即,丢弃)并且对于每个新的加载进行线的重新获取,以允许线程程序轮询由CPU写入的系统存储器的位置。如表I所示,应用于PPUDRAM地址的Id.cv与Id.cs相同,回收-优先。LD.cop[全局地址丨LD.cop[本地地址].copLIL2DRAML2SvsMem.copLIL2.ca*回收-正常回收-正常回收-正常.ca*回收-正常回收-正常.eg不-缓存[I]回收-正常回收-正常.eg回收-优先回收-正常cs回收-优先回收-优先回收-优先.Iu最后使用[2]回收-优先.CV不-缓存[I]回收-优先获取易失的[3].CV回收-优先回收-优先表I*指示缺省值。[I]在Id.eg或者Id.cv之前,LI使匹配的线无效。在这个实现方案中,LI不是连贯的-其没有对全局的写进行监听,所以匹配的LI线可能会失去时效。在Id.eg或者Id.cv之后,在LI中没有留下记录。[2]只有在线被完全覆盖(其所有数据均由warp的线程读取)的时候,LI将会返回本地的每线程的数据,然后使线无效并且取消待定的脏的回写取消;否则,其将返回该线并且以回收-优先的方式加以保留。[3]应用于系统存储器的加载易失高速缓存Id.cv使匹配的L2线无效并且对于每个新的加载进行线的重新获取,以允许线程程序轮询由CPU写入的SysMem位置。L2可以将爆发的加载合并(coalesce)到同一个SysMem地址。应用于巾贞缓冲DRAM地址的Id.cv与Id.CS相同,回收-优先。存储指令高速缓存操作St.cop与上述加载指令类似,存储指令具有可选的由.cop所指定的高速缓存操作,编译器和程序员可以用其来优化对全局存储器空间和本地每个线程的专用存储器空间进行访问的高速缓存使用。关于存储指令st{.cop}和st.e.{.cop}的可选高速缓存操作是.wb回写全部连贯的级别(缺省值).eg在全局级别进行高速缓存(在L2和以下的级别,而非LI上进行高速缓存).eg高速缓存流,有可能被写入一次(绕过高速缓存或者提前回收.wt高速缓存透写(write-through)(对于在系统存储器中的地址)在一个实施例中,当将共享存储器实现为RAM的时候,忽略对共享存储器的高速缓存操作。与那些用于全局存储器的高速缓存操作相比,对于本地存储器的高速缓存操作可以具有不同的含义。缺省的st通用存储高速缓存操作是存储回写(write-back)st.wb,其利用正常的回收策略回写连贯高速缓存级别的高速缓存线。,利用回写将被存储到本地每线程的存储器中的数据在LI高速缓存和L2高速缓存中进行高速缓存。然而,在一个实施例中,由于对于全局数据来说多个LI高速缓存是不连贯的,因此不对LI中的全局存储数据进行高速缓存。全局存储绕过了LI高速缓存并且将任何匹配的LI高速缓存线丢弃,而不考虑.cop高速缓存操作。其它的实施例可提供全局连贯的LI高速缓存,并且st.wb可以从LI高速缓存中回写脏的全局储存数据。在表2所示的一个实施例中,如果一个线程绕过其LI高速缓存器存储到全局存储器,并且在不同的SPM中的第二个线程随后利用Id.ca经由不同的LI高速缓存来加载那个地址,那么第二个线程可能命中失去时效的LI高速缓存数据,而不是从L2或者存储器得到由第一个线程所存储的数据。相应地,驱动器必须使线程阵列的附属栅格之间的全局LI高速缓存线无效。然后由第一格栅程序进行的存储会在LI高速缓存中得到正确地忽略,并被发布了缺省Id.ca加载的第二栅格程序所获取。该高速缓存操作st.eg全局高速缓存,仅全局性地用于对全局储存数据进行高速缓存,绕过LI高速缓存,以及仅在L2高速缓存中进行高速缓存。在表2所显示的一种实现方案中,st.eg高速缓存全局策略还可用于针对全局数据的st.wb指令,但是针对本地存储器的st.eg使用LI高速缓存,并且将本地LI线标记为回收-优先。该st.cs存储高速缓存流操作,利用回收-优先策略在L2高速缓存(和LI高速缓存,如果是本地的话)中分配高速缓存线,以限制由流输出数据导致的高速缓存污染;全局流数据绕过LI。自程序发布一次流写入后,st.cs的另一个实现方案将使流数据经由小的流高速缓存或者与每个高速缓存相邻接的先入先出(FIFO)来绕过LI和L2高速缓存,以使流数据不会对LI高速缓存或者L2高速缓存的工作集形成干扰。该st.wt存储透写操作,被应用于全局系统存储器地址,其将对L2高速缓存进行透写操作,以允许CPU程序利用St.Wt来轮询由PPU所写入的系统存储器位置。在一个实现方案中,不在系统存储器中的地址使用正常的L2回写。存储指令高速缓存操作的一个实施例采用在表2中所示的高速缓存操作策略。权利要求1.一种用于管理处理单元中的并行高速缓存层级的方法,该方法包括从调度器单元接收指令,其中所述指令包括加载指令或者存储指令;确定所述指令包括高速缓存操作修饰符,所述修饰符识别用于在所述并行高速缓存层级的一个或多个级别上对与所述指令相关联的数据进行高速缓存的策略;以及执行所述指令,并且基于所述高速缓存操作修饰符对与所述指令相关联的所述数据进行高速缓存。2.如权利要求I的方法,其中所述指令进一步地与识别存储器区域的地址相关联,其中用于对数据进行高速缓存的所述策略以所述存储器区域为基础。3.如权利要求2的方法,其中如果所述地址位于本地存储器区域之中,则对所述数据进行高速缓存,并且如果所述地址位于全局区域中,则不对所述数据进行高速缓存。4.如权利要求I的方法,其中所述并行高速缓存层级包括LI高速缓存级别以及L2高速缓存级别。5.如权利要求4的方法,其中包括在所述处理单元中的每个处理器都包括位于所述LI高速缓存级别上的不同的LI高速缓存,所述L2高速缓存级别包括每个处理器经配置均可对其进行访问的至少一个L2高速缓存。6.如权利要求4的方法,其中实现所述高速缓存操作修饰符,以使得对与所述指令相关联的所述数据在LI高速缓存级别和L2高速缓存级别上进行高速缓存。7.如权利要求6的方法,其中利用回收-优先的回收策略,对与所述指令相关联的所述数据在所述LI高速缓存级别和所述L2高速缓存级别的每一者上进行高速缓存。8.如权利要求4的方法,其中实现所述高速缓存操作修饰符,以在加载指令之后,无效和丢弃被高速缓存在所述LI高速缓存中的所述数据。9.如权利要求4的方法,其中实现所述高速缓存操作修饰符,以使得对与所述指令相关联的所述数据在所述L2高速缓存级别上进行高速缓存,而非在所述LI高速缓存级别上进行闻速缓存。10.如权利要求9的方法,其中利用回收-优先的回收策略,对与所述指令相关的所述数据在所述L2高速缓存级别上进行高速缓存。11.如权利要求I的方法,其中实现所述高速缓存操作修饰符,以使得利用回写策略或者透写策略,对与存储指令相关联的数据进行高速缓存。12.如权利要求I的方法,其中实现所述高速缓存操作修饰符,以使得利用易失性始终获取策略,对与加载指令相关联的数据进行高速缓存。13.一种用于管理并行高速缓存层级的系统,该系统包括处理器,其被配置为接收指令,其中所述指令包括加载指令或者存储指令,确定所述指令包括高速缓存操作修饰符,所述修饰符识别用于在所述并行高速缓存层级的一个或多个级别上对与所述指令相关联的数据进行高速缓存的策略,以及执行所述指令,并且基于所述高速缓存操作修饰符对与所述指令相关联的所述数据进行高速缓存。14.如权利要求13的系统,其中实现所述高速缓存操作修饰符,以使得利用回写策略或者透写策略,对与存储指令相关联的数据进行高速缓存。15.如权利要求13的系统,其中实现所述高速缓存操作修饰符,以使得利用易失性始终获取策略,对与加载指令相关联的数据进行高速缓存。全文摘要一种用于管理处理单元中的并行高速缓存层级的方法。该方法包括从调度器单元接收指令,其中该指令包括加载指令或存储指令;确定该指令包括高速缓存操作修饰符,该修饰符识别用于在并行高速缓存层级的一个或多个级别上对与指令相关的数据进行高速缓存的策略;以及执行该指令,并且基于该高速缓存操作修饰符对与该指令相关联的数据进行高速缓存。文档编号G06F9/30GK102713837SQ201080053153公开日2012年10月3日申请日期2010年9月23日优先权日2009年9月23日发明者布雷特·W·库恩,约翰·R·尼科尔斯,迈克尔·C·希巴侬申请人:辉达公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1