分块矩阵乘法运算系统的制作方法

文档序号:21319488发布日期:2020-06-30 20:50阅读:402来源:国知局
分块矩阵乘法运算系统的制作方法

本发明涉及数字矩阵的乘法运算,尤其涉及由专用硬件加速器辅助进行矩阵运算的处理器。



背景技术:

人工智能技术,尤其是深度学习,对于可以具有几百行和几百列的大矩阵的乘法运算(multiplication)要求特别高。因此,出现了专用于混合精度矩阵的乘法运算的硬件加速器。

大矩阵的乘法运算通常在块(block)中执行,即通过将矩阵分解成尺寸适合于计算资源的子矩阵。加速器因此被设计成有效地计算这些子矩阵的乘积。

例如,nvidia在其volta图形处理器中提供被称为张量核(tensorcore)的硬件操作符,每个操作符独占处理器的数个图形核的资源,以并行执行子矩阵乘法运算中涉及的许多计算。nvidia还在其集成的xavier处理器中提供了具有独立于图形核的张量核的nvdla(“nvidia深度学习加速器”)单元,并且专用于加速神经推理

这种加速器被称为“弱耦合”,因为它接收由主处理器(hostprocessor)准备的成批执行的任务,然后独立于主处理器管理任务,包括访问共享存储器以读取矩阵数据。加速器和主处理器因此异步操作,由此主处理器和加速器竞争存储器访问,并且必须定期同步,以便主处理器恢复任务结果并传送新任务。



技术实现要素:

通常提供一种用于矩阵相乘的方法,包括以下步骤:

a)在共享存储器中以行优先格式存储第一源矩阵,由此矩阵的行的连续元素被存储在连续的存储器地址;

b)在共享存储器中以列优先格式存储第二源矩阵,由此矩阵的列的连续元素被存储在连续的存储器地址;

c)在通过n位存储器总线从共享存储器到处理器寄存器的单个传输周期中:

读取源矩阵中的n位字;

将该字的k个连续分段写入k个相应的n位寄存器中的指定位置,

k使得n可被k整除;

e)对第一源矩阵的k=r个不同行执行步骤c),以便填充r个第一寄存器,由此r个第一寄存器中的每一个包含:在寄存器的r个连续分段中组织的n/r个位的r个行的不同子矩阵;

f)对第二源矩阵的k=q个不同列执行步骤c),以便填充q个第二寄存器,由此q个第二寄存器中的每一个包含:在寄存器的q个连续分段中组织的n/q个位的q个列的不同子矩阵;和

g)响应于子矩阵乘法机器指令的执行,使用专用硬件操作符并行地执行第一操作数寄存器的每个分段与第二操作数寄存器的每个分段的标量乘积(scalarproduct),该子矩阵乘法机器指令将r个第一寄存器中的一个指定为第一操作数,并且将q个第二寄存器中的一个指定为第二操作数,操作数寄存器的分段被视为向量。

该方法还可以包括以下步骤:在处理器的中央处理单元cpu中接收负载分散机器指令;响应于负载分散指令,将步骤c)委托给耦合到cpu的协处理器,寄存器和分段的位置由负载分散指令指定;在cpu中接收子矩阵乘法指令;和响应于子矩阵乘法指令,将步骤g)委托给协处理器。

cpu和协处理器可以根据vliw架构而耦合,该方法包括同时执行被包含在由cpu接收到的相同指令分组中的负载分散指令和子矩阵乘法指令的步骤,由此负载分散指令准备下一个操作数子矩阵,同时子矩阵乘法指令对当前操作数子矩阵进行操作。

硬件操作符可以被配置为将由指令指定的目的地寄存器的相应分段中的每个标量乘积与相应分段的先前内容进行累加,该方法包括以下步骤:执行子矩阵乘法指令r次,同时每次在r个第一寄存器和q个第二寄存器以及目的地寄存器的相同集合当中指定相同等级(rank)的不同操作数寄存器对。

每个源矩阵的元素具有8、16和32位当中的可配置精度。

提供一种处理器,包括:n位数据总线,被配置为访问存储器;中央处理单元cpu,被连接到数据总线;协处理器,被耦合到cpu,该协处理器包括具有n位寄存器的寄存器文件;cpu中的指令处理单元,被配置为响应于由cpu接收到的负载分散机器指令,读取对存储器地址的访问,并将对数据总线上呈现的对应的n位字的处理委托给协处理器;和协处理器中的寄存器控制单元,其由cpu响应于负载分散指令而被配置为将数据总线上呈现的字划分成k个分段,并将该k个分段写入k个相应寄存器中的相同位置,该位置和寄存器由负载分散指令指定。

协处理器可以包括点乘积(dot-product)硬件操作符的数组,每个操作符被配置为同时执行被包含在两个相应操作数寄存器的两个分段中的两个向量的标量乘积,操作数寄存器中的两个分段的等级由操作符在操作符数组中的位置确定,并且操作数寄存器由cpu接收到的子矩阵乘法机器指令来指定,由此操作数寄存器包含相应的操作数子矩阵,并且操作符数组产生结果子矩阵。

操作符可以被配置为在由子矩阵乘法指令指定的目的地寄存器的相应分段中累加标量乘积。

每个操作数子矩阵的元素可以具有8、16和32位当中的可配置精度。

附图说明

关联附图,将在以下非限制性描述中描述实施例,其中:

图1是集成强耦合到中央处理单元的协处理器的处理器的框图;

图2a至图2d示出了从存储在存储器中的矩阵数据来填充协处理器寄存器的不同步骤;

图3是协处理器硬件计算单元的实施例的框图,该协处理器硬件计算单元被设计成响应于单个机器指令而实现两个子矩阵的乘法运算;

图4是在图3的计算单元中使用的点乘积操作符的框图;

图5是协处理器硬件计算单元的另一实施例的框图,该协处理器硬件计算单元被设计成响应于单个机器指令而实现两个子矩阵的乘法运算;

图6是在图5的计算单元中使用的点乘积操作符的框图;

图7是可配置点乘积操作符实施例的框图;和

图8是协处理器硬件计算单元的实施例的框图,该协处理器硬件计算单元被设计成响应于单个机器指令而实现不同尺寸的子矩阵的乘法运算。

具体实施方式

在将存储在共享存储器中的矩阵数据馈送到加速器的计算单元而不导致计算单元稀缺或这些单元利用不足的方面,专用于矩阵乘法运算的硬件加速器面临困难。例如,用于在存储器中存储数据的格式可能不适合于计算单元所需的格式,使得可能引入等待时间和数据缓冲器来重组数据。

当加速器弱耦合(wealycoupled)并且与指挥加速器任务的主处理器异步操作时,这些困难被加剧。实际上,各自独立操作的主处理器和加速器在访问共享存储器时可能会相互冲突。此外,主处理器和加速器之间的同步机制可能导致其中一个或另一个在等待同步状态出现时停止。

当矩阵元素在数个可能性当中具有可配置的精度时,会出现附加的困难。

为了减轻这些困难,本文公开了一种处理器架构,将强耦合(strongcoupled)的协处理器与它自己的寄存器文件以及用于在存储器和协处理器寄存器之间传输数据的特殊机制集成在一起。

图1是这种处理器架构的框图。它包括强耦合到协处理器12的通用中央处理单元(cpu)10,协处理器12集成专用于矩阵乘积的计算的硬件操作符。通过“强耦合”,可以理解,协处理器服从在cpu中执行并由硬件执行单元14实施的逐周期机器指令(cyclebycyclemachineinstructions)。

更具体地,处理器指令集中的一些机器指令合并专用于协处理器的命令。当这些指令到达cpu的对应执行单元14时,执行单元通过控制线ctrl配置协处理器操作。协处理器被连线以立即服从存在于这些控制线上的信号。事实上,协处理器是cpu的执行单元14的扩展,服从处理器的通用指令集的扩展。因此,除了使执行单元适应协处理器控制之外,cpu10可以是通用类型,尤其允许执行操作系统或从通用编程语言编译的程序。

协处理器12包括硬件代数计算单元16,包括专用于矩阵乘法运算的计算的硬件操作符。协处理器还集成它自己的工作寄存器的集合,或寄存器文件18,独立于cpu10的常规寄存器文件20。

寄存器文件18和20由n位数据总线d连接到共享存储器22。未示出服从常规cpu执行单元的地址和存储器控制总线。协处理器的寄存器18具有与数据总线相同的尺寸n,并且被配置为服从来自cpu的执行单元14的命令。

要相乘的两个矩阵[a]和[b]最初被存储在共享存储器22中。取决于所使用的编程语言,矩阵默认以行优先格式(row-majorformat)存储,即相同行的元素位于连续地址,或者以列优先格式(column-majorformat)存储,即相同列的元素位于连续地址。c编程语言使用第一格式,而fortran使用第二格式。在任何情况下,这些编程语言所使用的标准线性代数库(standardlinearalgebralibrary,blas)提供转换参数,以根据计算的需要将矩阵从一种格式切换到另一种格式。

对于当前架构的需要,要相乘的两个矩阵以互补的格式存储,例如,第一矩阵[a]以行优先格式存储,而第二矩阵[b]以列优先格式存储。矩阵[b]因此以转置形式存储。图1示出了具有x+1行和y+1列的矩阵[a]以及具有y+1行和z+1列的矩阵[b]的存储器内容。矩阵[b]具有的行数等于矩阵[a]的列数,矩阵[b]可以乘以矩阵[a]。

协处理器12被设计成以完全硬件的方式将源矩阵的两个子矩阵(具有固定行数q的第一子矩阵[a],和具有固定列数的第二子矩阵[b],假设此时该固定列数等于q)相乘。子矩阵的剩余尺寸(以下称为深度)可以根据矩阵元素的期望精度来配置。因此,这些子矩阵的乘法运算产生qxq个元素的结果子矩阵[c]。

数字q决定了执行乘法运算所需的硬件资源。对于人工智能应用,值q=4提供了合理的折衷,并将在下面用作示例。事实上,在人工智能计算中,在浮点、分数或整数表示中使用8位或16位数字(很少是32位),使得操作符不如处理通用cpu中常规使用的“单精度”和“双精度”浮点数(分别被编码为32位和64位)所需的那些操作符复杂。

此外,要相乘的每个子矩阵被认为具有n位的总尺寸,即数据总线d的尺寸,作为下面的示例,将被假设为256位。因此,在下面考虑的示例中,子矩阵具有4行或4列,并且深度为64位。取决于应用,该深度由八个字节、四个16位字、两个32位字或一个64位字占用。它们可以是整数、固定数或浮点数。

给定这种结构,一个目的是给协处理器提供一系列要相乘的子矩阵,同时充分利用存储器总线d。理论上,只采取两次读取操作来读取与两个子矩阵相对应的数据量。但是一般来说,存储器中源矩阵的组织不直接允许这样做。实际上,存储器中的256个连续位与任意深度的连续行(或列)重叠,并且不包含可以形成子矩阵的4个对齐的子行(或子列)。

为了解决这一复杂问题,处理器指令集由特殊机器指令被扩展,该特殊机器指令被称为“负载分散(load-scatter)”指令,并且对于k=4,它具有标记为load.0至load.3的k个变量。负载分散指令指定协处理器的k个寄存器18以及读取256位字w的存储器地址,对于k=4,k个寄存器18被标记为v0至v3。当在cpu10中执行指令而存储器将字w放置在总线上时,协处理器12的寄存器控制单元被配置为将字w划分成k个n/k位的分段(segment),并将这些分段分别写入k个指定寄存器中。换句话说,字w在寄存器中是“分散的”。在指定寄存器中写入分段的位置由所执行的负载分散指令的变体来决定。

图2a至图2d示出了对深度超过256位的源矩阵[a]和[b]执行负载分散指令的变体。作为示例,假设矩阵元素是16位字。

在图2a中,执行load.0指令。指令中传送的存储器地址是指例如矩阵[a]的第一行的第一元素,即元素a[0][0]。因此,在总线上返回的字w0包含元素a[0][0]至a[0][15]。指令变体将寄存器v0至v3配置为在其第一个四分之一接收字w0的相应四个分段。

在图2b中,执行load.1指令。存储器地址是指元素a[1][0]。因此,在总线上返回的字w1包含元素a[1][0]至a[1][15]。指令变体将寄存器v0至v3配置为在其第二个四分之一接收字w1的相应四个分段。

在图2c中,执行load.2指令。存储器地址是指元素a[2][0]。因此,在总线上返回的字w2包含元素a[2][0]至a[2][15]。指令变体将寄存器v0至v3配置为在其第三个四分之一接收字w2的相应四个分段。

在图2d中,最终执行load.3指令。存储器地址是指元素a[3][0]。因此,在总线上返回的字w3包含元素a[3][0]至a[3][15]。指令变体将寄存器v0至v3配置为在其第四个四分之一接收字w3的相应四个分段。

在这四个负载分散的末尾,寄存器v0至v3中的每一个都包含沿着源矩阵[a]的行的连续的4x4的16位字(也称为4x4x16)的子矩阵[a]。每个子矩阵的行被包含在对应寄存器v的四个相应分段中。包含子矩阵[a]的寄存器v0至v3将被指定为va0至va3。

通过以四个寄存器vb0至vb3对第二矩阵[b]以类似的方式进行处理,这些寄存器中的每一个都接收沿着源矩阵[b]的列的连续的4x4x16子矩阵[b]。每个子矩阵的列被包含在对应寄存器vb的四个相应分段中。

利用该过程,可以被相乘的四个子矩阵[a]和四个子矩阵[b]在八个连续的时钟周期内被加载到协处理器的寄存器中。这实现了每个周期一个子矩阵的传输速率,这是最佳的,因为在每个周期使用完全的总线宽度。

包含子矩阵行或列的寄存器va和vb的分段将在下文中被视为向量。因此,寄存器vai包含四个向量a[0]至a[3],并且寄存器vbj包含四个向量b[0]至b[3],每个向量具有四个16位分量。

图3是协处理器的硬件计算单元16的实施例的框图,该协处理器被设计成响应于将被标记为mm4a的单个专用机器指令来执行两个子矩阵[a]和[b]的乘法运算。该实施例对应于图2a至图2b中考虑的示例,其中矩阵元素具有16位的尺寸。

计算单元包括4x4硬件点乘积和累加操作符(dot-product-and-accumulateoperator)(被命名为dp4a)的数组,其中数字4表示向量的维数。行i和列j的dp4a操作符被连线以执行分别被包含在寄存器va和vb中的向量a[i]和向量b[j]的标量乘积,并且在结果子矩阵[c]的单元cij中累加标量乘积。单元cij可以是协处理器的寄存器vc的适当尺寸的分段的全部或部分。一个方便的尺寸是64位,这涉及四个寄存器vca至vcd来存储结果子矩阵[c]。寄存器va、vb和vc由在cpu10中执行的指令mm4a指定,这里是寄存器va0、vb0和vc0a-vc0d。

寄存器vc被配置为保留寄存器va和vb的q个分段的组织。在该示例中,在q=4并且每个结果元素被编码在64位上的情况下,寄存器vc的4个分段中的每一个分段都包含单个元素。如示例所示,寄存器vc被组织成使得相同寄存器的四个分段存储来自不同行的元素。

一旦完成了对结果子矩阵的计算,在这种包含单个元素的分段的特定情况下,四个寄存器vc的内容可以在四个周期内在与完整结果矩阵[c]中的子矩阵[c]的列的位置相对应的地址被传送到存储器,从而得到以列优先格式存储结果矩阵[c]。

寄存器vc也可以以互补的方式组织,使得相同寄存器的四个分段存储不同的列元素。在这种情况下,四个寄存器vc的内容可以在四个周期内在与完整结果矩阵[c]中的子矩阵[c]的行的位置的相对应的地址被传送到存储器,从而得到以行优先格式存储结果矩阵[c]。

优选地,处理器指令集由机器指令扩展,用于转置包含q个寄存器的元组。在q=4的情况下,指定为mt4的该指令获取指定为vca、vcb、vcc、vcd的四个寄存器的内容,并填充指定为vda、vdb、vdc、vdd的其他四个寄存器,使得:

vda在其分段中分别接收vca、vcb、vcc和vcd的第一分段。

vdb在其分段中分别接收vca、vcb、vcc和vcd的第二分段。

vdc在其分段中分别接收vca、vcb、vcc和vcd的第三分段。

vdd在其分段中分别接收vca、vcb、vcc和vcd的第四分段。

执行该指令后,寄存器vca、vcb、vcc、vcd中的每一个都可以存储在存储器中,以有助于以行优先格式存储结果矩阵[c]的一行。

图4是操作符数组中位置(i,j)处的点乘积操作符dp4a的框图。操作符处理向量a[i]和b[j]。更具体地,操作符包括四个16位乘法器mul,每个乘法器mul接收向量a[i]的相应分量(ai0至ai3)作为第一被乘数,以及接收向量b[j]的相应分量(b0j至b3j)作为第二被乘数。被编码在32位上的四个乘积被提供给多加法器40,该多加法器40被连接以在64位寄存器分段cij中累加乘积的总和。通过“累加”,它意味着分段cij接收乘积的总和以及分段cij先前内容的总和。多加法器40因此被连线以添加四个32位数字和一个64位数字。

理论上,图3的计算单元,以有线组合逻辑的形式,响应于指定要被使用的寄存器va、vb和vc的指令mm4a而立即产生结果矩阵[c]。实践中,考虑到组合逻辑的传播延迟,这种计算单元将花费一个以上的处理器时钟周期来建立结果。因此,计算单元,特别是每个操作符dp4a,通常被设计成流水线结构,这意味着计算被分解成在连续时钟周期内同步的数个步骤,但是也意味着可以启动新的计算,即在每个时钟周期执行新的指令mm4a。

因此,流水线结构对于执行独立计算不是最佳的。然而,通过适当组织连续计算以保持流水线永久供应,流水线结构在初始流水线启动阶段之后和最终流水线排空阶段之前可以100%有效。

事实上,使用负载分散指令将八个子矩阵预加载到协处理器寄存器中(图2a-图2d),以及根据计算单元可立即使用的组织,要相乘的子矩阵因此在寄存器中可用,这使得维持至少为四个子矩阵乘积的计算提供的流水线成为可能。可以通过执行指定相同目的地寄存器vc的四个连续mm4a指令来执行的这四个子矩阵乘积提供了4x4结果矩阵[c],该结果矩阵[c]是4x16源子矩阵与16x4源子矩阵的乘积。

此外,协处理器和cpu之间的高度耦合配置允许处理器以vliw(verylargeinstructionword,超长指令字)架构来组织。然后,可以在相同的vliw分组中执行负载分散指令和mm4a指令,由此并行执行这两个指令,这占用存储器总线来检索下一个子矩阵,同时对当前子矩阵执行计算。

下面的表1呈现了一系列指令,这些指令实现了8x32矩阵[a]与32x8矩阵[b]的乘法运算,提供了8x8矩阵[c]而没有时滞(deadtime),并且并行利用了计算单元和存储器总线的所有带宽。放置在相同线上的指令对应于在相同vliw分组中执行的指令。为了表示法的紧凑性和清楚性的原因,协处理器寄存器对于被乘数子矩阵由ax和by来指定,对于结果子矩阵由cz来指定,请记住,所有这些从寄存器文件18中选择的寄存器具有相同的性质。

指令的第一参数标识目的地寄存器。指令的后续参数通常地标识存储器地址或操作数寄存器——这里使用了解释符号,其详细说明了目的地寄存器接收的内容。假设在操作之前所有寄存器c都被设置为0,或者操作符由mm4a指令的标志来配置,以在第一次写入寄存器c时禁用累加,这是通过符号“=”(直接写入)而不是符号“+=”(累加)来示出的。

阶段0和1对应于关于图2a-图2d描述的内容。

表1

在阶段9和清空计算单元流水线所需的一些周期之后,寄存器c0至c15包含从乘法运算产生的矩阵,即8x8x64矩阵。

应当注意,阶段6至9重用(reuse)阶段2至5的c寄存器,即相同的结果子矩阵c[0..3][0..3]、c[0..3][4..7]、c[4..7][0..3]和c[4..7][4..7]。事实上,在阶段2至5期间,仅在源矩阵深度的前半部分上(元素0至15)计算子矩阵c[][]。在阶段6至9中,利用源矩阵深度的后半部分(元素16至31)的影响来更新子矩阵c[][]。通过利用矩阵[a]和[b]的深度中的以下(following)256位截片(slice)的影响来更新c[][]子矩阵,该计算自然延伸到任何深度。

作为示例提到的源矩阵的深度是存储器总线的宽度n的倍数。当该属性不适用时,影响行(或列)的最后部分的负载分散操作读取第一部分包含行(或列)结尾、第二部分包含不可用数据(未对齐的行或列的开头,或矩阵结尾之后的任意数据)的字。在这种情况下,字的第二部分中的数据被零替换,并且因此重新调整的字如上所述被正常地处理。

如前所述,矩阵的深度根据为元素选择的精度而变化。在上面,考虑了16位元素的矩阵。元素也可以是8或32位长,而不影响存储器中源矩阵的组织或它们到协处理器寄存器的传输。然而,可以在协处理器的计算单元16中实现一些修改。

图5是协处理器的计算单元16的实施例的框图,计算单元16被设计成响应于将被指定为mm8a的单个专用机器指令来执行8位元素的两个子矩阵[a]和[b]的乘法运算。

源矩阵的元素从存储器到协处理器的寄存器va和vb的传输以与以前相同的方式执行,并利用一系列的四个负载分散指令。结果,如操作数寄存器va0和vb0所示,寄存器的四个分段现在包含八个8位元素的向量,而不是四个16位元素的向量。

点乘积操作符(这里称为dp8a)然后被配置为同时计算八个乘积及其总和。结果的精度是32位而不是64位,因此只需要两个寄存器vc0a和vc0b来存储结果子矩阵[c]。

如示例所示,寄存器vc被组织成使得每个分段存储结果子矩阵的两个行元素。例如,寄存器vc0a在其相应分段中包含对(c00,c01)、(c10,c11)、(c20,c21)和(c30,c31)。在这种情况下,两个寄存器vc的内容不能以正确的顺序直接传输到存储器以形成结果矩阵[c]的4x4子矩阵。

利用常规的存储指令,将花费8个周期来存储寄存器vc0a和vc0b的内容来以行优先格式形成结果矩阵[c],即四个周期仅使用四分之一总线宽度来传输寄存器vc0a的四个分段,然后四个周期仅使用四分之一总线宽度来传输寄存器vc0b的四个分段。这导致75%的带宽浪费。

优选地,通过与负载分散指令互补的指令(其将被称为“收集-存储(gather-store)”指令)来扩展处理器指令集。由cpu对该指令的执行将协处理器配置为在存储器总线上级联从q个指定寄存器中获取的q个分段。分段在寄存器中的位置由指令的对应变体来定义。

在该示例中,在q=4的情况下,执行四个收集-存储指令来处理包含两个结果子矩阵的四个寄存器vc0a、vc0b、vc1a和vc1b。这种机制通过颠倒箭头的方向而类似于图2a-图2d的机制。

在第一周期中,字w0包含寄存器vc0a的第一分段的元素c00、c01,接着是寄存器vc0b的第一分段的元素c02、c03,接着是存储在寄存器vc1a和vc1b的第一分段中的第二子矩阵的第一行的四个元素(未示出)。剩余的三个周期类似地传输两个子矩阵的第二至第四行。这样,在以行优先格式存储的结果矩阵中,两个相邻的子矩阵以行优先格式形成,完全占用总线带宽。

关于图3,指出了寄存器vc0a至vc0d的内容可以使用常规存储指令在四个周期内传输到存储器,以形成以列优先格式存储的结果矩阵。相反,使用四个收集-存储指令,将子矩阵以行优先格式写入存储器。换句话说,在每个寄存器vc恰好包含四个元素的特定情况下,子矩阵可以取决于所选存储指令的类型而按行或列传输到存储器,这是通过完全占用总线带宽实现的。

在q=4的情况下,使用收集-存储指令的替代方法是使用先前描述的mt4转置指令,其允许在一个周期内从寄存器vc0a、vc0b、vc1a、vc1b来填充四个寄存器vd0a、vd0b、vd1a、vd1b。寄存器vd0a、vd0b、vd1a、vd1b然后可以通过完全占用总线带宽以常规方式写入以行优先格式存储的结果矩阵。

图6是操作符数组中位置(i,j)处的点乘积操作符dp8a的框图。它包括八个8位乘法器,每个8位乘法器接收向量a[i]的相应分量(ai0至ai7)作为第一被乘数,并且接收向量b[j]的相应分量(b0j至b7j)作为第二被乘数。编码在16位上的八个乘积被提供给多加法器40b,该多加法器40b被连接以在32位寄存器分段cij中累加乘积的总和。

类似地,当矩阵元素是32位字时,从存储器到协处理器寄存器的传输再次以相同的方式、利用一系列的四个负载分散指令来执行。然后,寄存器分段包含两个32位元素的向量。点乘积操作符然后被指定为dp2a,并且它们在64或128位寄存器分段中累加两个32位数字的乘积。矩阵乘法指令然后被指定为mm2a。

图7是用于处理精度在8、16和32位当中可调的矩阵元素的可配置点乘积操作符实施例的框图。它包括两个32位数字乘法器、两个16位数字乘法器和四个8位数字乘法器,这些数字乘法器的输出被提供给多加法器40c,多加法器40c被连接以在64或128位寄存器分段cij中累加乘积的总和。

仅示出了与第一操作数向量ai相关的连接。对应的寄存器分段的所使用的位用方括号表示。

32x32乘法器被连接以处理向量的前两个分量,而不管它们的精度如何。2x32位向量的两个分量中的每一个都被应用于32x32乘法器中的相应一个乘法器的所有输入线。其他乘法器产生零结果。

16x16乘法器被连接以处理4x16或8x8位向量的第三分量和第四分量。对于4x16位向量,前两个分量中的每一个分量都被应用于两个32x32乘法器中的相应一个乘法器的前16个输入线,并且接下来两个分量中的每一个分量都被应用于两个16x16乘法器中的相应一个乘法器的所有输入线。

对于8x8位向量,前四个分量分别被应用于两个32x32乘法器和两个16x16乘法器的前8个输入线,并且其余分量分别被应用于8x8乘法器的所有输入线。

乘法器输入端和寄存器之间的互连结构由执行的矩阵乘法指令(即mm2a、mm4a或mm8a)的性质决定。

如前所述,矩阵元素可以是整数或浮点数(在后一种情况下,优选使用16位和32位精度)。乘法器和加法器被相应地配置。如果希望处理整数和浮点数两者,则乘法器将具有基于浮点乘法运算结构的可重配置的结构。

当矩阵元素具有32位精度时,已经提出结果的精度可以是64位或128位。如果接受一定程度的误差,诸如处理整数时的饱和,或者处理固定数或浮点数时的四舍五入的误差,64位的精度可能就足够了。

在呈现的示例中,认为要相乘的两个源矩阵具有相同精度的元素。所公开的架构还可以乘以混合精度矩阵。例如,在16位元素的矩阵[a]与8位元素的矩阵[b]的乘法运算的情况下,可以提供以下操作。

四个寄存器a0-a3由第一组四个负载分散指令填充,以包含从源矩阵[a]的前四行获取的四个4x4x16子矩阵。换句话说,这些子矩阵包含行a[0][0...15]至a[3][0...15]。

另外四个寄存器a4-a7由第二组四个负载分散指令填充,以包含从矩阵[a]的接下来四行获取的四个4x4x16子矩阵。换句话说,这些子矩阵包含行a[4][0..15]至a[7][0..15]。

四个寄存器b0-b3由第三组四个负载分散指令填充,以包含从矩阵[b]的前四列获取的八个4x4x8子矩阵。换句话说,这些子矩阵包含列b[0..31][0]至b[0..31][3]。

寄存器b0的两半部分包含两个子矩阵,其中一个子矩阵b[0..3][0..3]可以乘以寄存器a0的子矩阵a[0..3][0..3],以得到结果子矩阵c[0..3][0..3]。寄存器b0的另一个子矩阵b[4..7][0..3]可以乘以寄存器a4的子矩阵a[4..7][0..3],以得到结果子矩阵c[4..7][0..3]。换句话说,寄存器b0的两半部分的乘法运算被组织成得到结果矩阵[c]的两个不同子矩阵。

寄存器b1的两半部分包含两个子矩阵,这两个子矩阵可以分别与寄存器a1和a5的子矩阵相乘,以分别得到相同的结果子矩阵c[0..3][0..3]和c[4..7][0..3]。

类似地,寄存器b2的两半部分分别包含要与寄存器a2和a6的子矩阵相乘的两个子矩阵,并且寄存器b3的两半部分分别包含要与寄存器a3和a7的子矩阵相乘的两个子矩阵,每次都得到相同的结果子矩阵c[0..3][0..3]和c[4..7][0..3],即在这些操作期间不改变寄存器vc。

为了乘以寄存器的内容,乘法运算操作mm4a的两个变体可以在两个连续的周期中使用,指定两个不同的寄存器a(例如a0和a4)、一个对应的寄存器b(例如b0)、以及两组两个寄存器c来包含结果。参考图3中的4x4x16子矩阵乘法运算单元,两种变体首先将dp4a操作符配置为仅使用乘法器的b输入(称为半输入(half-input))中的8个最低有效位(leastsignificantbit)。第一变体另外重新配置操作符,以将十六个8位半输入连接到寄存器b0的分段bi0至bi3中的每一个分段所包含的前四个字节。相反,第二变体重新配置操作符,以将十六个8位半输入连接到寄存器b0的分段bi0至bi3中的每一个分段所包含的最后四个字节。

在混合精度矩阵乘法运算应用中,可以想到两个被乘数矩阵在位数方面尺寸相同,并且因此低精度矩阵的元素数大于高精度矩阵。因此,8位元素的被乘数矩阵的行数或列数可能是对应的16位元素的被乘数矩阵的两倍。在这种情况下,计算单元可以被设计成将qxqx16子矩阵乘以qx(2q)x8子矩阵,或者相反地乘以(2q)xqx8矩阵。

图8是从图3的计算单元推导的针对q=4的对应计算单元的示例,该计算单元被配置为通过从寄存器va0和va1中的两个4x4x16子矩阵和寄存器vb0中的4x8x8子矩阵产生两组寄存器vc中的两个结果4x4子矩阵,来响应mm4a指令的两个先前指示的变体的同时执行。考虑将寄存器vb0细分成两半部分,每半部分具有4个分段,每个分段包含一个4字节向量,并且dp4a点乘积操作符被组织成两个4x4数组,这两个4x4数组同时处理寄存器vb0的相应的两半部分。

在更一般的情况下,可以提供计算单元,该计算单元包括以rxq数组组织的点乘积操作符,其中r>q。在这种情况下,负载分散指令被配置为在第一系列的r个周期中填充r个不同的寄存器a,并且在第二系列的q个周期中填充q个不同的寄存器b。然后,每个寄存器a包含具有尺寸为n/q位的元素的q个行的子矩阵,并且每个寄存器b包含具有尺寸为n/r位的元素的q个列的r/q子矩阵,其中n是存储器总线的宽度和寄存器的尺寸,并且可被q和r整除。每个乘法运算指令读取r/q个寄存器a和一个寄存器b的内容,以产生尺寸为rxq的子矩阵。

为了使寄存器a和寄存器b的子矩阵能够相乘,它们的向量应该具有相同的尺寸。值n优选地是等于存储器总线尺寸的常数,这意味着如果q≠r,则两个子矩阵具有不同的精度元素。实践中,根据为8、16和32位当中的矩阵选择的精度组合,q和r可以按1、2或4的比率变化。

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