数据处理系统的制作方法

文档序号:12603820阅读:287来源:国知局
数据处理系统的制作方法与工艺

本发明涉及数据处理系统,并且具体地,涉及包括一个或更多个可编程处理级(“着色器(shader)”)的图形处理系统的操作。



背景技术:

图形处理通常按流水线方式来执行,并且一个或更多个流水线级(stage)针对数据进行操作以生成最终渲染(render)输出,例如,被显示的帧。许多图形处理流水线现在包括一个或更多个可编程处理级,通称为“着色器”。例如,图形处理流水线可以包括以下中的一个或更多个,并且典型地包括全部:几何着色器、顶点着色器以及片段(像素)着色器。这些着色器是可编程处理级,它们针对输入的数据值执行着色器程序以生成需要的输出数据集(例如,在顶点着色器的情况下,恰当地变换并照亮顶点数据),以供图形流水线的其余部分处理和/或输出。图形处理流水线的着色器可以共用可编程处理电路,或者它们都可以是独特的可编程处理单元。



技术实现要素:

图形处理单元(GPU)着色器核心是这样的处理单元,即,其通过针对诸如渲染目标的要生成的图形输出(例如,帧)中的每一个图形项运行小程序来执行图形处理(在这点上,“项”通常是顶点或片段(像素))。这通常使能实现高度并行性,因为典型的渲染输出(例如,帧)展现了相当大量的顶点和片段,每一个顶点和片段都可独立处理。

要由图形处理流水线的指定“着色器”执行的着色器程序将由需要利用高级着色器编程语言(如GLSL、HLSL、OpenCL C等)的图形处理的应用来提供。着色器程序将由表示按相关语言标准(规范)定义的希望编程步骤的“表达式”构成。接着,高级着色器程序被着色器语言编译器翻译成用于目标图形处理流水线的二进制代码。该二进制代码将由“指令”构成,所述指令在用于所指定的目标图形处理流水线的指令集规范中指定。用于将着色器语言表达式转换成二进制代码指令的编译处理可以经由编译器内的程序的许多中间表述来进行。因此,用高级着色器语言编写的程序可以被翻译成编译器专用中间表示(并且在该编译器内可以有几个连续中间表示),并且最终中间表示被翻译成用于目标图形处理流水线的二进制代码指令。

改进着色器执行效率的一种已知方式是将执行线程(其中,每一个线程例如对应于一个顶点或一个片段(像素))分组成线程“组”或“束”,其中,一组中的线程一次一个指令地锁步运行,即,该组中的每一个线程在移动到下一指令之前执行相同的单一指令。这样,可以在该组中的所有线程之间共享指令装入(fetch)和调度资源。(用于这些线程组的其它术语包括:“子组”、“warp”以及“波前(wavefront)”)。为方便起见,在此将使用术语线程组,但这旨在涵盖所有等同术语和排布结构,除非另外加以表明)。

在这种线程组中,针对每一个线程执行共享指令,并且在特定线程需要存储器存取(例如,针对加载、存储以及原子(atomics))时,通过该线程获取“锁定(lock)”,以确保独占地存取该线程访问的存储器中的数据,即,排除其它线程访问该存储器位置,每一个线程都获取独立的锁定。然而,因为该线程不能保证所有情况下的独立前向进展(因为由一个线程执行的一些步骤可能取决于其它线程执行的其它步骤),所以一个线程获取的锁定可能造成整个线程组的死锁。这接着造成这些线程中的一个或更多个无限期地拖延,等待该锁定变得可用。

例如,简单的代码序列

可以非直观地死锁。

这是因为该序列需要代码流分支(divergence),并且来自分支路径(即,具有不同程序计数器)的线程必须从执行中掩蔽掉。在具有“最低程序计数器优先(lowest program counter first”)”安排策略的系统中,未获得锁定的线程因此有利,但这些线程接着无限期地空转,等待所述锁定。

该问题的一种解决方案是将代码重新排序,以适应所用特定系统的调度行为,例如,利用下列代码序列:

然而,这要求编译器不优化指令序列,或者支持针对指令的语义排序。

因此,申请人认为,存在改进线程组的处理的余地,例如,在包括一个或更多个着色器级的图形处理流水线中。

根据本发明的第一方面,提供了一种操作数据处理系统的方法,所述数据处理系统包括执行流水线,所述执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程被一起组合成线程组,其中,所述线程组中的线程一次一个指令地锁步执行,该方法包括以下步骤:

针对要由所述数据处理系统的所述执行流水线的执行级针对线程组执行的、包括存储器事务的操作来说:

向所述执行级发出指令或指令集,以使所述执行级:

针对作为整体的线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果,并且

响应于所述指令或指令集,所述执行流水线的所述执行级:

针对作为整体的线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

根据本发明的第二方面,提供了一种数据处理系统,该数据处理系统包括:

执行流水线,该执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程被一起组合成线程组,其中,所述线程组中的线程被一次一个指令地锁步执行;以及

编译器,该编译器编译针对所述执行流水线的程序,以生成用于所述执行流水线的所述执行级的指令,

其中,所述编译器被配置成,针对所述执行流水线的执行级要针对线程组执行的、包括存储器事务的操作:

向所述执行级发出指令或指令集,以使所述执行级:

针对作为整体的线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果,并且

其中,所述执行流水线的至少一个执行级被配置成响应于所述指令或指令集:

针对作为整体的线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

本发明涉及执行数据处理流水线中的操作,其中,执行线程被一起组合成线程组(“warp”),并且线程组中的线程被一次一个指令地锁步执行,即,线程组中的每一个线程在移动到下一指令之前执行相同的单一指令。线程组可以包含任何合适和需要数量的线程。优选地,线程组由四个单独线程组成。

在本发明中,针对要执行的一个或更多个操作(涉及存储器事务的操作),向所述执行流水线的可编程执行级发出针对所述操作由线程组的所述线程执行的指令或指令集。所述指令或指令集针对作为整体的所述线程组执行,并且线程组(warp)范围的操作的结果被递送至所述线程组中的所有活动线程。(活动线程是当前正在执行指令或者正在等待执行指令的线程,即,与已经分支或终止它们的执行的不活动线程相反)。

由此,不针对所述线程组中的每一个线程来执行针对所述操作的所述指令或指令集,而是针对作为整体的所述线程组,由所述执行级来执行所述指令或指令集。

通过针对作为整体的所述线程组执行所述操作,即,针对以锁步执行的所有活动线程,有助于防止线程死锁。这是因为,针对线程组中的所有活动线程一起执行操作,使得在线程可以执行所述操作之前,没有线程必须等待针对另一线程的操作完成,例如,在利用锁来访问存储器的同时。

而且,因为针对作为整体的所述线程组来执行所述操作,并由此例如使各个线程单独地执行所述操作变得冗余,所以减少了所涉及的处理、所需带宽、所传递的数据以及由此消耗的电力。

所述操作可以包括涉及存储器事务的任何合适和需要的数据处理操作。

在优选实施方式中,所述操作包括原子操作(atomic operation)。“原子”存储器操作是读取存储器位置、在存储器值与寄存器值之间执行算术运算并接着将算术运算的结果写回至同一存储器位置的操作序列。执行该序列操作以使得对于每一个观察者来说,看起来好像该序列根本未执行或已全部执行。该序列操作作为一个不可分割的单元加以执行,因此叫做“原子”。

针对作为整体的所述线程组执行的所述原子操作可以包括任何合适和需要的原子操作。例如,所述原子操作可以包括置换操作,例如,包含用于改变一组数据的次序的置乱(shuffle)指令、(多个)类似低级指令(例如,缩减操作)、(多个)基本的算术指令(例如,加、减、除等)、或者(多个)比较或交换指令等。

在优选实施方式中,针对作为整体的所述线程组执行的所述原子操作包括锁定操作。“锁定”操作是这样的操作,即,针对获取所述锁定的执行线程保留独占地访问存储部(例如,存储器),以使其正在访问的存储部中的数据在所述锁定形成时不能被另一执行线程访问并由此潜在地改变。由此,一般来说,当锁定形成时,利用所述执行线程可以使用的所述数据来执行另一操作,例如,算术运算,并接着将其结果提供给所述线程组中的所述活动线程。

应当清楚,这种特定类型的原子操作(即,锁定操作)特别适于本发明,因为该操作有助于解决当一个或更多个线程在等待当前被另一线程保持的锁定时,线程组中的线程死锁的问题。通过针对作为整体的所述线程组获取并利用所述锁定,即,使得作为整体的所述线程组可以独占使用被所述线程组访问的存储器中的数据,这有助于防止所述线程死锁,因为不需要针对每一个单独线程的单独锁定。

用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的所述指令或指令集可以按任何合适和需要的方式来提供。优选地,用于所讨论的执行级的所述编译器包括发至所述执行流水线的所述指令集中的所述指令或多个指令,如下所述。

在一个优选实施方式中,用于针对作为整体的所述线程组执行所述操作的所述指令对于应用程序接口可见,因此程序员可以在针对要执行的所述操作的应用程序代码中明确地包括所述指令(其中,响应于此,所述编译器接着生成用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的指令或指令集)。

在实施方式中,所述编译器另外或者取而代之地被配置成(能够)自动(其自身的决断)提供用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的所述指令或指令集,即,不需要将所述指令或指令集例如通过程序员明确地包括在所述应用程序代码中。因而,优选的是,所述方法还包括以下步骤(并且所述编译器被配置成):自动将用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的指令或指令集插入用于所述操作的经过编译的应用程序代码中。

所述编译器可以自动地按任何合适和需要的方式来提供所述指令或指令集。例如,所述编译器可以被配置成在编译所述程序代码时,例如通过识别所述应用程序代码中的一个或更多个特定步骤,识别插入用于针对作为整体的线程组执行操作的指令或指令集的机会。

(当然,所述编译器可以不识别向执行级发出用于针对作为整体的所述线程组执行操作的指令或指令集的机会,在该情况下,所述编译器将不发出用于针对作为整体的线程组执行操作的指令或指令集,例如,如果未被确定为对所述操作的执行有益)。

用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的所述指令或指令集可以被配置成仅应用至单个线程组,其它线程组在执行所述操作时不遭遇该指令或指令集。然而,优选的是,为执行所述操作的所有线程组提供用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的所述指令或指令集,并且执行所述操作的所有所述线程组都遇到所述指令或指令集。

在优选实施方式中,所述编译器被配置成(能够)将所述程序代码中的步骤重新排序,例如,用于改进其针对线程组的执行效率。对于可以针对线程组中的每一个线程单独执行的操作(例如,每线程的锁定操作),例如,原子操作,因为这些操作可以自然分支,因而使编译器难于将它们优化,例如,因为对所述程序代码中的步骤重新排序可能引入死锁。然而,根据本发明,当针对作为整体的所述线程组来执行所述操作时,因为很少有死锁的风险,所以使得对于所述程序代码中的剩余其它步骤较容易重新排序。这意味着所述编译器可以较安全地对所述程序代码中的步骤重新排序,或者以降低的死锁风险来重新调度针对作为整体的所述线程组执行的所述操作。

因此,优选的是,所述方法包括以下步骤(并且所述编译器被配置成):相对于所讨论的着色器程序中的其它指令,对针对作为整体的线程组执行操作的指令或指令集(的发出)进行重新排序。由此,所述编译器可以向前或向后移动用于针对作为整体的线程组执行操作的所述指令或指令集。这种重新排序可以有助于优化(OpenCL)驱动器软件实现。

在优选实施方式中,仅针对作为整体的线程组执行所述操作一次,即,执行所述指令一次。由此,一旦已经针对作为整体的线程组执行了所述操作(例如,当线程组中的其中一个线程初始地遇到所述操作时),并且将所述操作的结果提供给所述线程组中的所有活动线程,在这个实施方式中,当例如所述线程组中的另一线程随后遇到所述操作时,不再执行所述操作。这是因为已经将所述操作的结果提供给所述线程组中的所有活动线程,因此遇到所述操作的线程可以通过简单地引用所述结果(例如,从寄存器读取)而非自身执行所述操作。

可以按照任何合适和需要的方式针对作为整体的所述线程组来执行所述操作,并且可以将所述操作的结果提供给所述线程组的所有活动线程。

在一个实施方式中,由所述执行级针对所述线程组的线程中的代表该线程组中的其它线程的一个线程执行所述指令或指令集,使得针对作为整体的所述线程组来执行所述操作,并且将所述操作的结果提供给所述线程组的所有活动线程。由此,当所述线程中的一个线程遇到(例如,因达到必要的程序计数器)所述指令或指令集(优选为第一线程遇到所述指令)时,所述执行级仅针对该线程(但代表作为整体的所述线程组)执行所述指令或指令集。

可以按任何合适和需要的方式,针对代表所述线程组中的其它线程的一个线程来执行所述指令或指令集。优选的是,将所述线程组中的、除正在被执行所述指令或指令集的线程以外的其它所有线程(例如,遇到所述指令或指令集)掩蔽掉,由此使这些被掩蔽的线程暂时不活动。遮蔽所述线程组中的所述其它线程防止在通过所述一个线程执行所述指令或指令集时这些线程遇到所述指令,使得针对作为整体的所述线程组执行操作。在执行了所述指令或指令集并将所述操作的结果提供给所述线程组的所有活动线程时,可以去除所述掩蔽。

因此,在一个优选实施方式中,所述方法包括以下步骤(并且所述执行级被配置成):当所述执行级接收到所述指令或指令集时,已针对所述线程组中的线程装入所述指令或指令集:除了已装入所述指令或指令集的所述线程以外,所述执行级掩蔽所述线程组中的所有(例如,活动)线程;并且所述执行级针对所述线程执行用于针对作为整体的所述线程组执行所述操作并且向所述线程组的所有活动线程提供所述操作的结果的所述指令或指令集。

在另一实施方式中,所述线程组中的每一个执行线程都被设置成在遇到所述指令或指令集时检查其它线程的状态,例如,检查另一线程是否已执行或开始执行所述指令或指令集。这有助于确保所述指令或指令集仅被执行一次,否则这可能导致所述线程和/或线程组死锁。在这种情况下,所述线程将不锁步执行。

在另一实施方式中,响应于所述指令或指令集,所述执行级针对所述线程组集总地执行所述操作,即,与针对代表所述线程组的一个线程执行所述指令或指令集的上述实施方式相比。因此,优选的是,所述方法包括以下步骤(并且所述执行级被配置成):当所述执行级接收到所述指令或指令集时,所述执行级针对所述线程组集总地执行所述指令或指令集。

可以按任何合适和需要的方式,针对所述线程组集总地执行所述指令或指令集。在一个实施方式中,所述执行级针对所述线程组执行所述指令或指令集(即,被设置成执行针对所述程序(例如,着色器)的所有其它指令的执行级,该程序针对所述线程组执行)。

在另一实施方式中,由与正在用于执行针对所述线程的操作的所述执行级分离的执行级执行所述指令或指令集,即,使得不针对特定线程(例如代表所述线程组)执行所述指令或指令集,而是单独地针对作为整体的所述线程组来执行。优选的是,所述单独的执行级包括标量引擎(scalar engine),例如,其被布置在用于所述线程组的所述执行级的旁边。所述单独的执行级(例如,所述标量引擎)因而被配置成向所述线程组的活动线程返回所述操作的结果。

一旦所述执行流水线的所述执行级执行了所述操作,就向所述线程组中的所有活动线程提供所述操作的结果,即,将统一(同一)结果提供给所有活动线程。(假定所述线程组中的任何不活动线程不需要所述操作的结果)。所述结果可以按任何合适和需要的方式提供给所述线程组中的所述活动线程。

在优选实施方式中,所述结果被提供给一个或更多个存储装置,例如,存储器或寄存器,所述结果可以被所述线程组中的所述活动线程读取。所述存储装置可以包括可由所述线程组中的所有活动线程读取的共享存储装置,例如,共享存储器或寄存器。这特别方便,因为可能存在将存储装置(例如,寄存器)用于作为整体的所述线程组的其它理由,例如,用于存储与执行针对所述线程组的操作而一起使用的其它数据。在另一实施方式中,针对所述线程组中的每一个活动线程,所述存储装置可以包括分离的存储装置,例如,分离(例如,专用)的存储器或寄存器。

在一个实施方式中,向所述线程组中的所述活动线程广播所述操作的结果,例如,所述执行级向所述活动线程发送消息,使得所述活动线程获知所述结果可例如从存储装置读取。

所述执行级可以与被提供了所述操作的结果的(多个)特定存储装置(例如,针对线程的寄存器)相关联,因此所述执行级可能已预先获知将所述操作的结果返回至哪里。在另一实施方式中,向所述线程组中的所有活动线程提供所述操作的结果的所述指令或指令集包含被提供所述操作的结果的所述存储装置(例如,寄存器)的位置的指示。该指示接着被所述执行级用于确定将所述操作的结果提供至哪里。

为允许将所述操作的结果提供给所述线程组中的活动线程,例如,通过向所述线程组中的活动线程广播消息和/或通过将所述结果提供给针对所述线程组中的每一个活动线程的单独存储装置,优选的是,所述执行级获知所述线程组中的哪些线程是活动的(当所述执行级包括标量引擎时特别是这种情况)。这可以按任何合适和需要的方式实现。优选的是,向所述线程组中的所有活动线程提供所述操作的结果的所述指令或指令集包括对所述线程组中的所述活动线程的指示。

在另一实施方式中,例如,其中,将所述操作的结果提供给针对所述线程组中的每一个活动线程的单独存储装置,将例如对针对不活动线程的寄存器的写入掩蔽掉,以防止将所述结果提供给这些线程。

根据本发明的方法和数据处理系统可以被设置成与执行时分支的程序代码一起工作。所述执行的分支可以发生在执行针对作为整体的所述线程组的所述操作之前和/或之后。如果在针对作为整体的所述线程组执行所述操作之前所述线程分支,则优选地,将所述分支(例如,不活动的)线程掩蔽,以帮助防止任何潜在死锁。

由此,可以仅针对在所述执行级执行所述指令或指令集时收敛(例如,自然收敛,尽可能合适)的那些线程执行所述操作。所述分支线程(即,在执行所述指令或指令集时,例如因在“if,then,or”语句下具有不同条件而不收敛的那些线程)被优选地掩蔽掉(例如,停止),并且不执行所述操作。优选的是,所述分支线程还包括任何不活动线程。这允许仅针对所述活动线程执行所述操作,并将结果仅提供给所述活动线程。

本发明还扩展至编译器本身。由此,根据本发明另一方面,提供了一种编译器,该编译器编译程序以生成针对执行流水线的执行级的指令,该执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程被一起组合成线程组,其中,该线程组中的线程一次一个指令地锁步执行,其中,所述编译器被配置成,针对要由所述执行流水线的执行级针对线程组执行的、包括存储器事务的操作:

向所述执行级发出指令或指令集,使所述执行级:

针对作为整体的所述线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

根据本发明另一方面,提供了一种编译程序以生成针对执行流水线的执行级的指令的方法,该执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程被一起组合成线程组,其中,该线程组中的线程一次一个指令地锁步执行,该方法包括以下步骤:

针对要由所述数据处理系统的所述执行流水线的执行级针对线程组执行的、包括存储器事务的操作:

向所述执行级发出指令或指令集,使所述执行级:

针对作为整体的所述线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

本发明还扩展至具有可响应于(和利用)本发明的指令来执行处理的一个或更多个执行级的执行流水线。

因此,根据本发明的另一方面,提供了一种用于数据处理系统的执行流水线,该执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程可以一起组合成线程组,其中,该线程组中的线程一次一个指令地锁步执行,其中:

在执行指令流中的指令时,响应于所述指令流中的、用于执行针对线程组的操作的指令或指令集,所述执行流水线的至少一个执行级被配置成:

针对作为整体的所述线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

根据本发明另一方面,提供了一种操作用于数据处理系统的执行流水线的方法,该执行流水线包括执行用于执行数据处理操作的指令的一个或更多个可编程执行级,并且其中,执行线程可以一起组合成线程组,其中,该线程组中的线程一次一个指令地锁步执行,该方法包括以下步骤:

所述执行流水线的至少一个执行级在执行指令流中的指令时,响应于所述指令流中的、用于执行针对线程组的操作的指令或指令集:

针对作为整体的所述线程组执行所述操作;以及

向所述线程组的所有活动线程提供所述操作的结果。

本领域技术人员应当清楚,本发明的这些方面在适当时候可以并且优选地包括在此描述的本发明的优选和可选特征中的一个或更多个或全部。

优选地,执行流水线的所有执行级(各执行级)可以按本发明的方式来工作。

各可编程处理级(执行单元)可以包括任何合适的可编程硬件部件,如可编程处理电路。各可编程处理级可被提供为独立于针对处理流水线的其它可编程级的电路部件,或者可编程处理级可以共用它们的可编程处理电路中的一些或全部(因而被不同地编程以用作需要的可编程处理级)。

如上所述,优选的是,本发明的数据处理系统包括图形处理系统,该图形处理系统包括图形处理流水线。在这种情况下,所述图形处理流水线可以被用于执行图形处理(在该情况下,优选的是,线程组中的每一个线程都对应于一个顶点或一个片段(像素)和/或采样点),但其还可以被操作为计算着色器流水线(例如,根据OpenCL)(在该情况下,每一个线程例如将对应于合适的计算着色器工作项)。

因此,所述执行流水线可以是图形处理流水线、计算着色器流水线等。

在这些排布结构中,所述图形(或其它)处理流水线优选地包括一系列不同的处理级,其中每一个都例如执行不同操作,以提供所述处理流水线的输出。优选的是,所述处理流水线包括一个或更多个(例如,多个)处理级,例如,所述处理级一起工作来实现本发明的操作。

对于图形和/或计算着色器处理流水线的情况来说,执行单元(级)优选地包括处理流水线的可编程着色级,诸如顶点着色器、片段着色器等。这些级可以如所需要地按任何合适的方式实现,并且可以分别和在合适时执行任何需要和合适的着色功能(例如,顶点着色、片段着色等)。对于片段着色器的情况来说,例如,该片段着色器可以渲染图元或多个图元以生成一组渲染输出值,例如,表示用于显示的帧。这些输出值接着可以被导出至外部存储器以供存储和使用,如导出到显示器的帧缓冲器。

除了可编程处理(着色器)级,图形处理流水线还可以包含图形处理流水线可包含的任何其它合适和需要的处理级,诸如光栅化器(rasteriser)、早期深度(或早期深度和模板)测试器、后期深度(或深度和模板)测试器、混合器(blender)、图块(tile)缓冲器、写出输出单元等。

本发明可以被用于图形(或其它)处理流水线可以用于生成的所有形式的输出,诸如用于显示的帧、渲染至纹理输出、计算着色器输出等。来自该处理的输出(例如,片段着色的)数据值优选地导出至外部(例如,主)存储器,以供存储和使用,如导出到显示器的帧缓冲器。

本发明可应用于任何合适形式或配置的图形处理器。特别可应用于基于图块的图形处理器和图形处理系统。由此,在优选实施方式中,图形处理系统和图形处理流水线分别是基于图块的系统和流水线。

在特别优选的实施方式中,本发明的各种功能在单个图形处理平台上执行,该单个图形处理平台生成并输出渲染的片段数据(例如被写入用于显示装置的帧缓冲器)。

本发明可以在任何合适系统中实现,如适当配置的基于微处理器的系统。在优选实施方式中,本发明在计算机和/或基于微处理器的系统中实现。

本发明的各种功能可以按任何需要和合适的方式来执行。例如,本发明的功能可以按需要以硬件或软件实现。由此,例如,除非以其它方式指出,本发明的各种功能部件、级以及“装置”可以包括合适的处理器或多个处理器、控制器或多个控制器、功能单元、电路、处理逻辑、微处理器装置等,它们可工作以执行各种功能等,诸如可以被编程成按需要方式工作的适当的专用硬件部件和/或可编程硬件部件。

在此,还应注意到,本领域技术人员应清楚,本发明的各种功能、级等可以在指定处理器上复制和/或并行执行。等同地,若需要,各种处理级可以共用处理电路等。

受限于执行上述特定功能所需要的任何硬件,该数据处理系统和流水线可以另外包括该数据处理流水线所包括的一般功能单元等中的任一个或更多个或全部。

本领域技术人员还应清楚,本发明的所有描述的方面和实施方式在合适时候可以(并且优选地)包括在此描述的优选和可选特征中的任一个或更多个或全部。

根据本发明的方法可以至少部分地利用软件(例如,计算机程序)来实现。由此,可以看到,当从另一方面观看时,本发明提供一种计算机软件、计算机程序元素以及计算机程序。在被安装在数据处理装置上时,该计算机软件特别适于执行在此描述的方法,计算机程序元素包括在数据处理装置上运行该程序元素时用于执行在此描述的方法的计算机软件代码部分,并且计算机程序包括当在数据处理系统上运行该程序时适于执行在此描述的方法或多个方法的全部步骤的代码手段。数据处理器可以是微处理器系统、可编程FPGA(现场可编程门阵列)等。

本发明还扩展至包括这种软件的计算机软件载体,其在被用于操作包括数据处理装置的图形处理器、渲染器或微处理器系统时,使与所述数据处理装置、所述处理器、渲染器或系统结合地执行本发明的方法的步骤。这种计算机软件载体可以是诸如ROM芯片、CD ROM、RAM、闪速存储器或磁盘的物理存储介质,或者可以是诸如通过导线的电子信号、光学信号或诸如到卫星的无线电信号等的信号。

还应清楚,不是本发明方法的所有步骤都需要通过计算机软件来执行,因此,根据本发明的更广泛方面提供一种计算机软件并且这种软件安装在计算机软件载体上、用于执行在此阐述的方法的步骤中的至少一个步骤。

因此,本发明的装置可以适当地具体实施为与计算机系统一起使用的计算机程序产品。这种实现可以包括固定在诸如计算机可读介质(例如,软盘、CD ROM、ROM、RAM、闪速存储器或硬盘)的有形非暂时介质上的一系列计算机可读指令。这种实现还可以包括可通过有形介质(包括但不限于光或模拟通信线路),或者无形地利用无线技术(包括但不限于微波、红外线或其他传输技术),经由调制解调器或其它接口装置传送至计算机系统的一系列计算机可读指令。所述一系列计算机可读指令具体实施先前在此描述的全部或部分功能。

本领域技术人员应当清楚,这种计算机可读指令可以采用许多编程语言来编写,以与许多计算机架构或操作系统一起使用。而且,这种指令可以利用当前或将来的任何存储器技术来存储,包括但不限于半导体、磁或光,或者利用当前或将来的任何通信技术来传送,包括但不限于光、红外线或微波。设想的是,这种计算机程序产品可以作为具有附随打印或电子文档(例如,收缩包装软件)的可去除介质进行分发,利用计算机系统预先加载(例如,预先加载在系统ROM或固定盘上),或者通过网络(例如,因特网或万维网)从服务器或电子公告板发布。

附图说明

下面,仅通过示例的方式并且参照附图对本发明的许多优选实施方式进行描述,其中:

图1示意性地示出示例性计算机图形处理系统;

图2示意性地示出了可以按本发明的方式工作的图形处理流水线;

图3示意性地示出了一组执行线程;

图4示出了图2所示的执行线程组的操作的流程图;

图5示意性地示出了可按本发明的方式工作的着色器核心的架构布局;

图6示出了可按本发明的方式工作的编译器的操作的流程图;

图7a、图7b及图7c示意性地示出了本发明的各个实施方式的执行操作;

图8a和图8b示意性地示出了本发明的各个实施方式的处理结果;以及

图9示出了根据本发明实施方式的操作的流程图。

具体实施方式

下面,在处理用于显示的计算机图形的背景下,对本发明的许多优选实施方式进行描述。

图1示意性地示出典型的计算机图形处理系统。

在主处理器1上执行的诸如游戏的应用2将需要由关联的图形处理单元(图形处理流水线)3来执行图形处理操作。为此,该应用将生成API(应用编程接口)调用,该API调用通过运行在主处理器1上的用于图形处理流水线3的驱动器4来解释,以生成针对图形处理器3的恰当命令,从而生成应用2所需的图形输出。为此,响应于来自运行在用于图形输出(例如,用于生成要显示的帧)的主系统1上的应用2的命令,将一组“命令”提供给图形处理器3。

图2更详细地示出了本实施方式的图形处理流水线3。

图2中示出的图形处理流水线3是基于图块的渲染器,因此将生成渲染输出数据阵列的图块(如要生成的输出帧)。

(在基于图块的渲染方面,不是如即时模式渲染中那样有效地一举处理整个渲染输出(例如,帧),而是将该渲染输出(例如,要显示的帧)划分成多个较小的子区域,通称为“图块”。每一个图块(子区域)都单独渲染(通常一个接一个),并接着将经渲染的图块(子区域)重新组合以提供完整的渲染输出,例如,用于显示的帧。在这种布置中,渲染输出通常被划分成规则大小和形状的子区域(图块)(例如通常是方形或矩形),但这不是必须的)。

渲染输出数据可以通常是旨在用于在显示装置(诸如屏幕或打印机)上显示的输出帧,但也可以包括例如旨在供以后渲染处理中使用的中间数据(也称为“渲染至纹理”输出)等。

在要显示计算机图形图像时,通常首先将其定义为一系列图元(多边形),接着将图元依次划分(光栅化)成用于图形渲染的图形片段。在正常的图形渲染操作期间,渲染器将修改与每个片段相关联的(例如)颜色(红、绿、蓝,RGB)和透明度(alpha a)数据,使得可以正确显示片段。一旦片段已经完全经过渲染器,则将它们的关联数据值存储在存储器中准备输出,例如用于显示。

图2示出了与本实施方式的操作相关的图形处理流水线3的主要部件和流水线级。本领域技术人员应当清楚,可以存在图2中未例示的图形处理流水线的其它部件。在此还应注意,图2仅是示意性的,而且例如实际上,所示的功能单元和流水线级可以共用大量硬件电路,即使它们在图2中被示意性地示出为单独的级。还应清楚,如图2所示的图形处理流水线的级、部件以及单元等中的每一个都可以如需地实现,并因此例如包括用于执行必要操作和功能的恰当电路和/或处理逻辑等。

如图2所示,图形处理流水线3包括多个级,这些级包括顶点着色器20、外壳着色器21、曲面细分器(tesselator)22、域着色器23、几何着色器24、光栅化级25、早期Z(深度)和模板测试级26、片段着色形式的渲染器27、后期Z(深度)和模板测试级28、混合级29、图块缓冲器30,以及下采样与写出(多重采样分辨)级31。

顶点着色器20采取与针对要生成的输出所定义的顶点等相关联的输入数据值,并且处理那些数据值以生成一组对应的“顶点着色”输出数据值,供图形处理流水线3的随后的级使用。顶点着色例如修改输入数据以在要渲染的图像中考虑光照效果。

外壳着色器21针对多组的片(patch)控制点执行操作,并且生成被称为片常数的附加数据,曲面细化级22细分几何形状以创建外壳的较高级表示,域着色器23对曲面细化级输出的顶点执行操作(类似于顶点着色器),而几何着色器24处理诸如三角形、点或线的整个图元。响应于提供给图形处理流水线3的命令和顶点数据,这些级与顶点着色器21一起有效地执行所有必要的片段前端操作(诸如变换与光照操作)和用于设置要渲染的图元的图元设置。

图形处理流水线3的光栅化级25工作以将组成渲染输出的图元(例如,要显示的图像)光栅化为个别图形片段以进行处理。为此,光栅化级25接收用于渲染的图形图元,将图元光栅化成采样点,并且生成具有恰当位置(表示恰当采用位置)的图形片段以渲染图元。

光栅化级生成的片段接着被向前发送至流水线的其余部分以供处理。

早期深度(Z)/模板测试级26对其从光栅化级25接收到的片段执行深度(Z)测试,以查看在该级是否可以废弃(剔除)任何片段。为此,早期Z/模板测试级26将从光栅化级25发出的片段的深度值(与片段相关联)与已经渲染的片段的深度值(这些深度值被存储在作为图块缓冲器30的一部分的深度(Z)缓冲器中)进行比较,以确定新的片段是否会被已经渲染的片段掩蔽。同时,执行早期模板测试。

通过了片段早期Z和模板测试级26的片段接着被发送至片段着色级27。片段着色级27对通过早期Z和模板测试的片段执行恰当的片段处理操作,以处理该片段来生成恰当的渲染片段数据。

该片段处理可以包括任何合适和需要的片段着色处理(诸如对片段执行片段着色器程序、向片段应用纹理、向片段应用雾化或其它操作等),以生成恰当的片段数据。在本实施方式中,片段着色级27采用着色器流水线的形式(可编程片段着色器)。

接着是“后期”片段Z和模板测试级28,其中,其针对着色片段执行流水线深度测试的末端,以确定在最终的图像中是否将实际看到渲染的片段。通过将从片段着色级27发出的片段的深度值(和片段相关联)与已渲染的片段的深度值(存储在深度缓冲器中)进行比较,该深度测试使用存储在图块缓冲器30的Z缓冲器中的片段位置的Z缓冲值,来确定新片段的片段数据是否应当替换已渲染的片段的片段数据。该后期片段深度和模板测试级28还对片段执行任何必需的“后期”alpha和/或模板测试。

通过后期片段测试级28的片段接着在混合级29中经受(若需要的话)与已存储在图块缓冲器30中的片段的任何必需的混合操作。对于片段而言必需的任何其它剩余操作(如抖动(dither)等)(未示出)也在该级执行。

最后,(混合的)输出片段数据(值)从它们例如可以被写到图块缓冲器30,并且从图块缓冲器30输出至帧缓冲器以进行显示。用于输出片段的深度值还被恰当地写入图块缓冲器30内的Z缓冲器。(图块缓冲器将存储颜色和深度缓冲,其针对该缓冲器表示的每一个采样点(本质上,针对被处理的图块的每一个采样点)分别存储恰当颜色等或Z值)。这些缓冲器存储表示总的渲染输出(例如,要显示的图像)的一部分(图块)的片段数据的阵列,并且缓冲器中的采样值的各个组对应于总的渲染输出的相应像素(例如,每个2×2组的采样值可以对应于输出像素,其中,使用4倍多重采样)。

图块缓冲器被设置为位于图形处理流水线(芯片)上(本地)的RAM的一部分。

来自图块缓冲器30的数据被输入至下采样(多重采样分辨)写出级31,并且从该处输出(写回)至外部存储器输出缓冲器,如显示装置的帧缓冲器(未示出)。(该显示装置例如可以包括具有像素阵列的显示器,诸如计算机监视器或打印机)。

下采样与写出单元31对存储在图块缓冲器30中的片段数据下采样,直至用于输出缓冲器(装置)的恰当分辨率(即,使得生成与输出装置的像素相对应的像素数据阵列),以生成用于输出至输出缓冲器的输出值(像素)。

一旦处理了渲染输出的图块并将其数据导出至主存储器(例如,主存储器中的帧缓冲器(未示出))以供存储,就接着处理下一图块,等等,直到处理了足够图块以生成整个渲染输出(例如,要显示的帧(图像))为止。接着,针对下一渲染输出(例如,帧)重复该处理等等。

用于图形处理流水线3的其它排布结构当然是可能的。

上面描述了图1所示的图形处理系统的操作的某些特征。下面,对根据本发明的实施方式的、图1所示图形处理系统的操作的进一步特征进行描述。

可以从图2看出,图形处理流水线3包括多个可编程处理或“着色器”级,即,顶点着色器20、外壳着色器21、域着色器23、几何着色器24以及片段着色器27。这些可编程着色器级执行具有一个或更多个输入变量并生成多组输出变量的、由应用提供的相应着色器程序。为此,应用2提供利用诸如GLSL、HLSL、OpenCL等的高级着色器编程语言实现的着色器程序。接着,这些着色器程序被着色器语言编译器翻译成用于目标图形处理流水线3的二进制代码。这可以包括在编译器内创建程序的一个或更多个中间表示。(编译器例如可以是驱动器4的一部分,并且存在使该编译器运行的专用API调用。该编译器执行由此可以被看作响应于应用生成的API调用,而通过驱动器进行的绘制调用准备的一部分)。

图形处理流水线中的每一个着色器(举例来说,如图2的实施方式中所示)是基于图形处理流水线从应用接收到的命令,通过针对要生成的图形输出中的每一个图形项运行小程序来执行图形处理(在这点上,“项”通常是顶点、片段或像素)的处理单元。本实施方式涉及如下情况:要由着色器执行的执行线程(其中,每一个线程都对应于一个图形项)已被组织成线程的“组”或“束”,所述线程将要一次一个指令地锁步运行并且要执行原子存储器操作(例如,锁定操作)。

(“原子”存储器操作是读取存储器位置、在存储器值与寄存器值之间执行算术运算并接着将算术运算的结果写回至同一存储器位置的操作序列。该序列操作被执行为使得对于每一个观察者来说,看起来好像该序列根本未执行或者已全部执行。该序列材质作为一个不可分割的单元加以执行,因此,叫做“原子”)。

图3示出了针对这种线程组的执行级51(“锁步单元”)的示意图,该执行级包括四个单独的执行路线(lane)52(“路线1”、“路线2”、“路线3”、“路线4”),这些执行路线执行针对个别线程的指令执行。针对线程,为每个执行线程52单独地提供由执行路线52执行的操作(通过执行指令或指令集)的结果53(“原子MSG#1”、“原子MSG#2”、“原子MSG#3”、“原子MSG#4”)。

图4是示出在执行原子操作时针对线程组(举例来说,如图3所示)的操作的流程图。首先,将用于原子操作的编译指令从指令高速缓冲存储器54中装入,并且例如由执行级解码(步骤61,图4)。该线程组中的执行线程皆利用要在原子操作中(例如,在算术运算中)中使用的、从线程的寄存器读取的数据来完成所述指令(步骤62,图4)。该原子操作由所述执行级针对每个线程执行(步骤63,图4),这通常涉及将数据写入至共享存储器区或高速缓冲存储器(步骤64,图4)。

一旦执行了该原子操作,就将该操作的结果53(“原子MSG#1”、“原子MSG#2”、“原子MSG#3”、“原子MSG#4”)(例如,因算术运算而对寄存器数据的修改)写回至用于该线程组中的每一个线程的寄存器(步骤65,图4),使得该结果可以被该线程组中的每一个线程读取。

图5至图9例示了上述操作的各种优选实施方式。

图5示出了根据本发明实施方式的着色器核心101(例如,图1所示的图形处理单元(流水线)3)的示意图。着色器核心101包括多个执行单元102(“warp单元”),其中每一个执行单元都支持四个执行线程的组。每个执行单元102都包括四组寄存器103(即,每个线程一组寄存器,并且每组寄存器优选地具有至少32个寄存器)以及共享的本地存储器区104(“存储库(storage bank)”)。

每一个执行单元102都与互连部105(“消息路径”)数据通信。而且,与互连部105进行数据通信的是标量执行单元106以及处理加载/存储和原子操作的分离“加载/存储/原子”流水线107,例如,针对外部系统存储器或高速缓冲存储器层级。

下面,参照图6的流程图,对根据本发明实施方式的用于着色器核心的编译器的操作进行描述。

如上所述,当关联的图形处理单元(图形处理流水线)要执行应用的图形处理操作时,该应用将生成由编译器(未示出)接收的API(应用编程接口)调用(例如,作为着色器程序的一部分)(步骤71,图6)。这使得编译器能够生成针对图形处理单元的恰当指令,以生成该应用所需的图形输出。这些指令对于每一个线程组(要针对其执行着色器程序)来说是公共的,例如,绘制调用。

API调用由编译器解析(步骤72,图6),并且编译器标识要执行的或者可以在线程组范围的基础上执行的操作(步骤73,图6)。

如果API调用在程序代码中明确地包括用于要针对作为整体的线程组执行的操作的步骤或多个步骤,则编译器将API调用编译成恰当的指令或指令集以发至图形处理单元进行执行(步骤74,图6)。

另外或另选地,如果编译器能够在着色器程序中包括用于以自己的意志针对作为整体的线程组来执行操作的指令或指令集,则编译器将通过针对作为整体的线程组执行操作,尝试在API调用中标识恰当的步骤和/或机会,以针对线程组来优化该着色器程序(步骤74,图6),如果编译器标识了这种步骤/机会,则自动将指令或指令集插入编译的着色器程序中。

接着,将编译的指令发至图形处理单元(步骤75,图6),例如,通过将指令写入指令高速缓冲存储器,执行级可针对线程组从指令高速缓冲存储器装入所述指令。

图7a、图7b、图7c、图8a及图8c皆示出了要用于执行线程组的执行的执行单元102(“锁步单元”)。类似于图5中示出的,执行单元102包括四个单独执行路线110(“路线1”、“路线2”、“路线3”、“路线4”),即,每执行线程一个路线。

在图7a、图7b、图7c及图8a所示的执行单元102中,仍然类似于图5中示出的,针对每个单独的执行路线110设置单独的一组寄存器103(“R1”)。

在图8b所示的执行单元102中,代替单独的寄存器,设置了可由每一个执行线程读取的共享寄存器111。

在图7c所示的系统中,类似于图5中示出的,设置标量执行单元106,标量执行单元106与针对执行线程组的执行单元102数据通信。

参照图5、图7a、图8a及图9,将首先对在执行针对作为整体的执行线程组的操作时该执行线程组的操作进行描述。

图9示出了示出根据如图7a所示的实施方式的由一组执行线程采取的执行步骤的流程图。

存储在指令高速缓冲存储器108中的编译的指令在被执行单元102的程序计数器(该程序计数器被每一个执行线程共享)引用时被该执行单元装入(步骤201,图9)。该线程组中的执行线程皆轮流完成所述指令,所述指令被该线程组中的每一个线程共享并锁步地执行。

评估每一个指令或指令集有关是否为是要针对作为整体的线程组执行的原子操作(步骤202,图9),直到该线程组中的线程之一遇到这种要针对作为整体的线程组执行的原子操作为止。(如果线程所遇到的指令不涉及要针对作为整体的线程组执行的原子操作,则在该指令或指令集被确定为不涉及这种操作(步骤202,图9)之后,该指令的执行与针对参照图2所述的操作相同)。

在原子级操作包括锁定操作的实施方式中,锁定操作程序代码可以采取这样的形式,即:

While(warp_mtx.try_lock());

//针对整个warp执行锁定工作

warp_mtx.unlock();

在一个实施方式中,这导致被发至该执行级的下列原子交换指令(用于获取和释放锁定):

WATOM32.lock.AXCHG r0,r1,d0//r0-src addr,r1-dst addr,d0-val,p=0

WATOM32.lock.AXCHG r0,d0,d1//r0-src addr,d0-dst,d1-val,p=0

第一指令交换该值(例如,其预期0,并且用1替换该值),以获取锁定(等同于“try_lock”指令),而第二指令交换该值(例如,保持该锁定时预期为1,接着用0替换该值),以释放锁定。

该指令采取下列引数(argument):

该指令利用跨该线程组的线程的锁定来执行原子交换操作。如果源(src)位置未设置,则该操作利用原子比较和交换操作,自动将该操作的结果存储至遇到该指令的第一个线程的目的地(dst)地址位置,以跳过该线程组中的所有其它活动线程。如果src位置已经被设置,则该操作返回结果0,否则,返回结果1。

如果该操作是原子加(add)操作,例如,没有利用锁定,则在一个实施方式中,该指令采取这样的形式,即:

WATOM64.atom.AADD r0,r1,d0//r0-src addr,r1-dst addr,d0-val,p=1

该指令自动执行针对遇到该指令的第一活动线程的源(src)地址位置的原子加操作,而该线程组中的其它活动线程组利用现有结果。作为该操作的结果,返回该操作之前源(src)地址位置中的旧值。

返回至图5、图7a、图8a及图9,当该线程组中的线程之一(例如,通过图7a中的“路线1”执行路线110执行)遇到用于要针对作为整体的线程组执行的原子操作的指令(从指令高速缓冲存储器装入(步骤201,图9))时,通过执行单元102将其识别为要针对作为整体的线程组执行(步骤202,图9)。执行单元102接着掩蔽掉该线程组中的其它线程(步骤203,图9),即,将它们呈现为不活动,如图7a所示。

(在这个阶段,如果要针对作为整体的线程组执行的原子操作包括锁定操作,则获取对该线程存取的存储器中的数据的锁定,由此有效地获取针对作为整体的线程组的锁定)。

来自与锁步单元102中的活动线程相对应的执行路线110的寄存器组103的数据接着被存取(步骤204,图9),以用于原子操作,例如,算术运算。接着,原子操作可以由与该线程相关联的执行路线110来执行(步骤205,图9),这通常涉及利用“加载/存储/原子”流水线107来执行针对共享存储器区的原子操作并且将数据写入该共享存储器区(步骤206,图9)。

一旦执行了原子操作,就将操作的结果(统一结果(“原子MSG”)113)(例如,因算术运算而修改的寄存器数据)写回执行级102的每一条执行路线110的寄存器组103(步骤207,图9)。如图7a和图8a所示(除了针对为了执行针对作为整体的线程组的操作而被掩蔽掉的任何执行路线以外),使得结果可以在该线程组中的每一个线程达到针对该原子操作的所述指令或指令集时由每一个线程存取。

在将操作的结果写入执行路线110的寄存器组103后,去除针对执行级102的执行路线110的掩蔽(步骤208,图9)。接着继续处理图形处理流水线从应用接收到的命令,即,完成从指令高速缓冲存储器装入的指令,并且只要要针对作为整体的线程组执行原子操作,就重复上面参照图5、图7a、图8a及图9描述的处理。

图7b所示实施方式的操作非常类似于针对图7a所示的实施方式描述的操作。唯一差异是,代替将针对遇到要针对作为整体的线程组执行的原子操作的线程的执行路线110(如图7a所示的“路线1”)用于执行该原子操作,由执行单元102针对作为整体的线程组来执行针对原子操作的指令或指令集,由此避免必须掩蔽掉任何执行路线110。与图7a所示实施方式类似地,将原子操作的结果写回针对执行单元102的执行路线110的寄存器组103中的每一个寄存器。

图7c所示实施方式的操作非常类似于针对图7b所示的实施方式描述的操作,除了代替执行单元102执行指令或指令集,通过单独的标量执行单元106来执行原子操作的执行(如图5所示)。与图7a和图7b所示实施方式类似地,将原子操作的结果写回针对执行单元102的执行路线110的寄存器组103中的每一个寄存器。

在另一实施方式中,如图8b所示,设置可由执行单元102中的每一个执行路线110读取的共享寄存器111。在这个实施方式中,向线程组中的所有活动线程提供原子操作的结果的步骤(步骤207,图9)包括:将该结果写入至共享寄存器111,针对单独线程的执行路线110可以从共享寄存器111读取该结果。

根据上述内容可以看出,针对作为整体的线程组(即,针对要锁步执行的所有线程)执行warp范围的操作有助于避免这些线程死锁。这是因为该操作针对该线程组中的所有线程共同执行的缘故,这样,在一个线程可以执行操作之前,不用等待另一线程完成该操作,例如在利用锁定访问存储器的同时。

而且,因为所述操作针对作为整体的所述线程组来执行,因此例如使得各个线程单独执行所述操作变得多余,所以缩减了所涉及的处理、所需的带宽、所传递的数据及由此消耗的功率。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1