首页> 中国专利> 插入用于优化的SIMD代码的操作-和-指示指令

插入用于优化的SIMD代码的操作-和-指示指令

摘要

提供了用于插入指示指令以在向量化代码的执行中追踪和指示异常的机制。接收第一代码(620)的一部分以供编译。分析第一代码(620)这一部分以识别第一代码(620)中执行指定的非预测性操作的非预测性指令,该非预测性指令是被替换的操作-和-指示指令所替换的候选者,操作-和-指示指令执行指定的非预测性操作并进一步执行指示操作,指示操作用于指示对应于出现在到该替换的操作-和-指示指令(1020)的向量寄存器输入中的特殊异常值(840)的任何异常条件。执行此替换(1080)并且基于对该至少一个非预测性指令的替换来生成第二代码(630)。执行经编译代码(630)的数据处理系统(100)被配置为响应于预测性指令生成异常条件,在向量输出寄存器(1130)中存储特殊异常值(840)而不启动异常处理。

著录项

  • 公开/公告号CN102473104A

    专利类型发明专利

  • 公开/公告日2012-05-23

    原文格式PDF

  • 申请/专利权人 国际商业机器公司;

    申请/专利号CN201080036667.7

  • 申请日2010-07-19

  • 分类号G06F9/45(20060101);

  • 代理机构11256 北京市金杜律师事务所;

  • 代理人王茂华;陈姗姗

  • 地址 美国纽约州阿芒克

  • 入库时间 2023-12-18 05:25:47

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2015-05-20

    授权

    授权

  • 2012-07-04

    实质审查的生效 IPC(主分类):G06F9/45 申请日:20100719

    实质审查的生效

  • 2012-05-23

    公开

    公开

说明书

本发明是在美国政府的支持下完成的,能源部授予的合同号为 B554331。美国政府具有本发明中的某些权利。

技术领域

本申请总体上涉及一种改进的数据处理装置和方法,更特别地 涉及一种用于插入用于优化的单指令流多数据流(SIMD)代码的操 作-和-指示指令机制。

背景技术

多媒体扩展(MME)已经成为通用微处理器的最为流行的附加 物之一。现有的多媒体扩展可以被特征化为支持打包的固定长度向 量的单指令流多数据流(SIMD)路径单元。传统的用于多媒体扩展 的编程模型通过使用(内嵌式)汇编或者嵌入在高级编程语言中的 内部函数而一直进行显式向量化编程。显式向量编程耗时且易出错。 一种有希望的选择是使用向量化技术从用标准高级语言编写的程序 中自动生成SIMD代码。

尽管用于传统向量处理器的向量化在几十年前就已经被广泛研 究,但是由于传统向量处理器和SIMD架构二者之间的多个基础性 差别,SIMD架构的向量化已经提出了新的问题。为了区分这两种类 型的向量化,后者被称为SIMD向量化、或者SIMD化。一个基础 性差别来自于存储单元。典型的SIMD处理器的存储器单元与传统 向量处理器的存储器单元相比,更像宽标量处理器的存储器单元。 在某些PowerPC微处理器(由New York,Armonk的国际商业机器 公司生产)上发现的VMX指令集中,例如,加载指令从16字节对 齐的存储器中加载16字节相连的存储器,忽略指令中存储器地址的 最后4位。这同样适用于存储指令。

编译器技术近来出现的兴趣点是从程序中自动提取SIMD并行 性。多媒体处理器和高性能计算中的SIMD架构的日益流行激励了 这一高潮。这些处理器具有多个功能单元,例如,浮点单元、定点 单元、整数单元等,这些功能单元可以在同一机器周期执行多于一 个指令以增强单处理器性能。这些处理器中的这些功能单元典型地 是流水线化的。

在执行基于编译器的循环变换以提取SIMD并行性时,重要的 是确保数组引用的安全性。也就是说,在编译用于由SIMD架构执 行的源代码期间,编译器可能执行不同的优化,包括确定代码中可 以被并行化以供SIMD架构执行的部分。这一并行化典型地涉及对 该代码部分进行向量化、或SIMD向量化、或SIMD化。这种优化 之一涉及将代码中的分支转换为预测操作以便避免流水线功能单元 遭遇分支误预测惩罚。这一优化涉及通过使用比较指令建立对应于 分支条件的布尔判断式来将源代码中的条件分支转换为具有预测操 作的预测代码。因此,现在保护指令的判断式,根据该判断式的值 或者执行该指令,或者无效(nullify)该指令,这一过程通常称为“如 果-转换”(if-conversion)。

总之,通过传统的“如果-转换”生成的预测代码通过执行来自 两个相互排斥的执行路径的指令来生成直线型代码,抑制对应于上 述两个相互排斥的执行路径中一个路径上的指令。当这些相互排斥 的执行路径中的其中一个不对应于选择的路径时,该路径会生成各 种各样不期望的错误执行结果,特别是非法存储器引用,这是相当 普遍的。因此,如果“如果-转换”不是用于无效与“如果-转换”一 致的非选择的预测指令,特别是,不是用于经“如果-转换”的代码 中的存储器引用指令,那么,“如果-转换”可能导致错误的执行。

Gschwind等人在2006年3月的IEEE Micro.的“Synergistic  Processing in Cell′s Multicore Architecture(Cell的多核架构中的协同 处理)”一文中提出了数据并行“如果-转换”的概念,这正被日益广 泛地用于数据并行SIMD架构的编译。不同于传统的标量“如果-转 换”,数据并行“如果-转换”通常瞄准大部分SIMD架构支持的具 有数据并行选择的代码生成,这在和本申请共同未决且共同受让的、 Gschwind等人的申请日为2006年8月4日、名称为“Method and  Apparatus for Generating Data Parallel Select Operations in a  Pervasively Data Parallel System(用于在常见数据并行系统中生成数 据并行选择操作的方法和装置)”的美国专利申请公开号 US20080034357A1中进行了描述,因为数据并行SIMD架构通常不 提供预测执行。

因此,传统的“如果-转换”利用指出执行或不执行对应于相互 排斥的路径之一或另一的每个指令的判断式来保护每个指令。在 Gschwind等人的专利申请公开文献中描述的具有数据并行选择的数 据并行“如果-转换”在没有判断式的情况下执行来自两条路径的指 令,并且刚好在其与原始的源代码中已采取路径对应时,使用数据 并行选择指令以选择对应于已编译代码中的无条件执行路径的结 果。因此,尽管数据并行选择可以被用于基于已采取路径的信息实 现结果选择,但是具有数据并行选择的数据并行“如果-转换”不适 用于无效指令。这是因为向量指令可能选择其结果向量的一部分, 而未选择其结果向量的另一部分,这使得传统的指令预测不可行。

针对如下示例代码,可以更容易理解传统“如果-转换”和使用 数据并行选择操作的数据并行“如果-转换”之间的差别,其中示例 代码用QPX汇编语言提供:

a[i]=b[i]/=0?1/b[i]:DEFAULT;

传统的“如果-转换”将以如下形式实施这一代码。

;init FRZEROS=register initialized with 0.0

;init FRDEFAULT=register preloaded with the fault of DEFAULT

LFD                  FBI=b[i]

FCMPEQ               predicate,FRZERO,FBI

FRE<NOT predicate>    FAI,FBI<===如果判断式指示b[i]/=0 则有条件地执行,并且如果b[i]==0,则抑制结果和异常)

FMR<predicate>        FAI,FRDEFAULT    <===如果判断 式指示b[i]==0则有条件地执行,并且如果b[i]/=0,则抑制移动)

QVSTFD    a[i]=FAI

可以看到,如果判断式条件指示不应当执行指令,那么结果和 所有关联的副作用,诸如异常,会被抑制。FRE将生成单个结果, 在这种情况下,结果被写入并且适当的时候引发异常,或者FRE不 写入单个结果,在这种情况下,结果没有被写入并且不引发异常。

现在考虑通过SIMD向量化和利用数据并行选择的数据并行“如 果-转换”而生成的代码,例如,在示例性的4元素向量上:

;init QRZEROS=vector with 0.0 elements

;init QRDEFAULTS=vector with DEFAULT elements

QVLFD       QBI=b[i:i+3]

QVFRE       QTRE,QBI  <====如果允许向量指令引发异常, 可能引发虚假的被零除)

QVFCMP      QTC,QRZEROS,QBI

QVFSEL      AQI,QTRE,QRDEFAULTS,QTC

QVSTFD      a[i:i+3]=QAI

根据这个例子,QVFRE指令没有被预测,并且总是写入结果。 如上所述,FRE指令将或者写入其结果,因为它生成了单个结果, 在这一情形下,单个结果被写人并且在适当的时候引发异常,或者 FRE指令不写入单个结果,在这种情况下,结果没有被写入并且不 引发异常。与FRE指令不同,QVFRE指令可能生成将要写回到向量 a[i:i+3]中的0、1、2、3或4个结果,以。然而,关于是否将使用结 果的知识对于QVFRE指令而言是不可获得的,因此,它不能生成正 确的异常集合。

因此,在编译器使用数据并行“如果-转换”生成SIMD化的代 码以供在SIMD处理器架构中执行的情况下,异常被抑制以避免虚 假错误。然而,重要的是能够保留应用行为,甚至异常的产生。

发明内容

在一个示意性实施方式中,提供一种数据处理系统中的方法, 用于插入指示指令以在向量化代码的执行过程中追踪和指示异常。 该方法包括由在数据处理系统的处理器上执行的编译器接收第一代 码的一部分。该方法进一步包括由在处理器上执行的编译器分析第 一代码的这一部分,以识别第一代码中执行指定的非预测性操作的 至少一个非预测性指令,该非预测性指令是被操作-和-指示指令替换 的候选者,操作-和-指示指令执行该指定的非预测性操作并进一步执 行指示操作,该指示操作用于指示对应于出现在到替换的操作-和- 指示指令的向量寄存器输入中的特殊异常值的任何异常条件。该方 法还包括由在处理器上执行的编译器用替换的操作-和-指示指令替 换第一代码中执行指定的非预测性操作的该至少一个非预测性指 令。此外,还方法包括由在处理器上执行的编译器基于该至少一个 非预测性指令的替换来生成第二代码。数据处理系统被配置为响应 于预测性指令生成异常条件,在向量输出寄存器中存储特殊异常值, 而不启动异常处理。

在其他示例性实施方式中,提供了包括具有计算机可读程序的 计算可用或者可读介质的计算机程序产品。当计算机可读程序在计 算设备上执行时,引起计算机设备执行上面关于方法示例性实施方 式概述的各种操作以及操作的组合。

在另一示例性实施方式中,提供了一种系统/装置。该系统/装置 可以包括一个或多个处理器,以及耦合到该一个或多个处理器的向 量寄存器文件。一个或多个处理器被配置为引起该一个或多个处理 器执行上面关于方法示例性实施方式概述的各种操作以及操作的组 合。

本发明的这些以及其他的特征和优点将在以下本发明的示例实 施例的详细说明中描述,由此,这些以及其他的特征和优点将对本 领域普通技术人员变得明显。

附图说明

当结合附图来阅读并参考对示例实施方式如下的详细描述时, 本发明及其优选使用模式和进一步的目的和优点将变得更好理解, 其中:

图1是示例实施方式的诸多示例性方面可以在其中实施的异构 多处理器片上系统的示例框图;

图2是为了讨论某些示例实施方式所做的改进的目的而展示的 已知处理器架构的框图;

图3是示例实施方式的诸多示例性方面可以在其中实施的图2 所展示的处理器架构的修改形式的示范图;

图4A和图4B是说明根据一个示例实施方式的、在一个或多个 向量元素上操作的数据并行选择操作的执行的示例图,其中向量元 素具有存储在向量元素中并被传播的异常值;

图5是说明根据一个示例实施方式的存储-和-指示指令的示例 图;

图6是根据一个示例实施方式的编译器的示例性框图;

图7A是说明根据一个示例实施方式的可以执行针对除法寄存 器上的溢出的测试以检测丢失异常条件的条件集合的示例图;

图7B是说明根据一个示例实施方式的可以执行针对操作数寄 存器上的溢出的测试以检测溢出到NaN的变化条件的条件集合的示 例图;

图8是概述根据一个示例实施方式的用于设置向量元素的值的 示例操作的流程图;

图9是概述根据一个示例实施方式的用于生成异常的示例操作 的流程图;

图10是概述根据一个示例实施方式的用于由编译器将指示指令 插入到SIMD向量化代码中的示例操作的流程图;

图11A-图11C是说明根据一个示例实施方式的标准的、可检查 的和不可检查的SIMD代码部分之间的差异的示例图;

图12A-图12C是说明根据一个示例实施方式的用于插入指示指 令的插入位置的示例图;以及

图13A-图13C是说明根据另一个示例实施方式的用于插入指示 指令的插入位置的示例图。

具体实施方式

示例实施方式提供了用于数据内路径上跟踪浮点异常和基于存 储的异常指示的机制。利用示例实施方式的机制,当遇到异常条件 时,如在指令的预测性执行或此类期间时,在向量元素中存储特殊 值。指令的推测性执行是执行线程的一部分,其是一种优化技术, 利用该优化技术,假如线程的结果在代码执行期间需要,也即,假 如线程被从预测性状态转变到使用这些结果的非预测性状态,则执 行其结果稍后可能需要也可能不需要的线程的早期执行使得达到更 大的性能。示例实施方式的特殊值指示异常条件,但不调用对应的 异常处理机器。这些特殊值通过计算机程序的执行而传播,并通过 具有向量的处理器架构传播直到该向量将要被存留在存储器中,诸 如通过非预测性指令,例如,存储操作、或者用于从向量寄存器向 另一个向量寄存器移动向量中的数据的移动操作。当执行这种非预 测性指令时,会生成真正的异常,并且执行适当的异常处理。这样, 异常条件的检测和异常处理是相互分开的,使得当异常条件实际上 影响计算机程序的执行时,例如通过将预测性指令的或指令集合的 执行变为非预测性,异常条件可以在执行流水线的一点上被检测, 并仅触发一个异常要被处理。

示例实施方式的机制优选地结合编译器实施,编译器将源代码 转换为用于在一个或多个能够执行向量化指令的处理器上执行的代 码,向量化指令例如单指令流多数据流(SIMD)指令。利用示例实 施方式的机制,在将源代码(例如标量代码)装换为SIMD向量化 代码时,在该代码的适当位置处插入操作-和-指示指令,例如,移动 -和-指示、存储-和-指示,或者此类的(它们共同被称为“指示”指 令),以利用特殊值来识别异常条件的出现。根据基于感兴趣的值 是可检查的还是不可检查的(将在之后定义)一种或多种方法,编 译器确定适当的插入点。在一种方法中,通过使用屏蔽机制,SIMD 代码中不可检查的部分可以被转换为可检查的SIMD代码。在一种 方法中,可以在涉及感兴趣的值(例如,感兴趣的值的数组)的每 个计算之后插入指示指令。在另一方法中,少量的检查指令被插入 在适当的位置以测试每一个活的输出值,在此,如果一个值最终影 响存储镜像或者代码的判决过程(或连续的计算将使用这一结果以 最终影响存储镜像或者代码的判决过程),则该值是活的。

提供支持SIMD的处理器的数据处理系统的一个例子是Cell宽 带引擎(CBE),其可以从纽约,Armonk的国际商业机器公司获得。 尽管以下描述将假定使用CBE架构来实施示例实施方式的机制,但 应当理解,本发明不限于与CBE架构一起使用。相反,示例实施方 式的机制可以与其中数组引用安全分析可以和编译器执行的变换一 起使用的任何架构一起使用。以下提供的CBE架构只是一类数据处 理系统的一个示例,在该示例中,可以利用示例实施方式的机制, 但是不旨在于陈述或者暗示关于示例实施方式的机制的任何限制。

本领域技术人员将会理解,本发明可以被具体化为系统、方法 或者计算机程序产品。因此,本发明的诸多方面可以采取以下形式: 全部以硬件体现、全部以软件体现(包括固件、驻留软件、微代码 等)、或者以软件和硬件方面的组合体现,其在此可被统称为“电 路”、“模块”或“系统”。此外,本发明的诸多方面可以采用包 含在具有计算机可用程序代码的任何一个或多个计算机可读介质的 计算机程序产品的形式。

可以使用一个或多个计算机可读介质的任意组合。计算机可读 介质可能是计算机可读的信号介质,或者计算机可读的存储介质。 计算机可读的存储介质,例如可以是但不限于,电的、磁的、光学 的、电磁的、红外的或半导体系统、装置、设备,或上述任何合适 的组合。计算机可读介质的更具体的例子(非穷举列表)将包括以 下内容:具有一个或多个导线的电连接、便携式计算机磁盘,硬盘、 随机存取存储器(RAM)、只读存储器(ROM),可擦除可编程只 读存储器(EPROM或闪存)、光纤、便携式紧凑磁盘只读存储器(CD ROM)、光存储设备、磁存储设备、或上述任何合适的组合。在本 文的语境中,计算机可读存储介质可能是任何有形介质,它可以包 含或存储用于供指令执行系统、装置或设备使用或与其结合使用的 程序。

计算机可读的信号介质可能包括例如在基带中或者作为载波的 一部分而传播的、其中体现计算机可读程序代码的传播的数据信号。 这种传播的信号可以采取的形式多种多样,包括但不限于,电磁的、 光学的、或它们任何适当的组合。计算机可读信号介质可以是并非 为计算机可读存储介质、但是可以传送、传播、或传输用于供指令 执行系统、装置或设备使用或与其结合使用的程序的计算机可读介 质。

包含在计算机可读介质上的计算机代码可能使用任何适当的介 质传输,包括但不限于无线、有线、光缆、射频(RF)等,或它们 的任何适当组合。

用于执行本发明诸方面的操作的计算机程序代码可以以一种或 多种编程语言的任意组合来编写,这些编程语言包括面向对象的程 序设计语言,例如JavaTM、SmalltalkTM、C++或类似的,还包括传统 的过程式程序设计语言,如“C”程序设计语言或类似的程序设计语 言。程序代码可以完全在用户的计算机上执行,部分在用户的计算 机上执行,作为一个独立的软件包执行,部分在用户计算机上部分 在远程计算机上执行,或者全部在远程计算机或服务器上执行。在 后一种情况,远程计算机可以通过任何类型的网络连接到用户的计 算机,网络可以包括局域网(LAN)或广域网(WAN),或者,可 以连接到外部计算机(例如,通过使用互联网服务提供商的互联网)。

以下参考根据本发明示例实施方式的方法、装置(系统)和计 算机程序产品的流程图和/或框图来描述本发明的诸方面。应当理解, 可以通过计算机程序指令来实现流程图和/或框图中的每个块,以及 流程图和/或框图中块的组合。这些计算机程序指令可以被提供给通 用计算机、专用计算机或其他可编程数据处理装置的处理器,以产 生一种机器,使得通过计算机或者其他可编程数据处理装置执行的 这些指令创建用于实施在流程图和/或框图中一个或多个块中规定的 功能/操作的装置。

这些计算机程序指令也可以存储在能够引导计算机、其他可编 程数据处理设备或其他设备以特定方式工作的计算机可读介质上, 使得存储在计算机可读介质中的指令产生一个包括实施在流程图和/ 或框图中的一个或多个块中规定的功能/操作的指令的制品。

计算机程序指令也可以被装载到计算机、其他可编程数据处理 设备或其他设备上,以引起计算机、其他可编程设备或其他设备上 的一系列操作步骤的执行,从而产生计算机实施的过程,使得在计 算机或者其他编程设备上执行的指令提供用于实施在流程图和/或框 图中一个或多个块中规定的功能/操作的过程。

附图中的流程图和框图说明了根据本发明的多个实施例的系 统、方法和计算机程序产品的可能实现的架构、功能和操作。在这 方面,流程图和框图中的每个块可能代表一个模块、分段、部分代 码,其包括用于实施规定的逻辑功能的一个或多个可执行指令,还 应当注意,在一些可替代的实施例中,方块中表明的功能可能不以 附图中表明的顺序发生。例如,连续示出的两个块,事实上是基本 上同时执行的,或者这些块有时候是按相反的顺序执行的,这取决 于涉及的功能。还应该注意到,框图和流程图中的每一个块,和框 图和流程图表中块的组合,可以通过执行特定功能或操作的专用的 基于硬件的系统来实现,或者可以用专用硬件和计算机指令的组合 来实施。

图1是本发明的诸方面可以在其中实施的数据处理系统的示例 性框图。图1所示的示例性数据处理系统是Cell宽带引擎(CBE) 数据处理系统的例子。尽管将使用CBE来描述本发明的优选实施例, 但本发明并不限于此,在阅读了以下的描述,这对本领域技术人员 将是显而易见的。

如图1所示,CBE 100包括具有处理器(PPU)116和它的L1 和L2高速缓存器112和114的Power处理器元件(PPE)110,和多 个协同处理器元件(SPE)120-134,每个协同处理器元件(SPE)具 有它们自己的协同处理器单元(SPU)140-154、存储器流控制 155-162、本地存储器或储存器(LS)163-170和总线接口单元(BIU 单元)180-194。总线接口单元例如可以是直接存储器访问(DMA)、 存储器管理单元(MMU)和总线接口单元的组合。还提供了高带宽 的内部元件互连总线(EIB)196、总线接口控制器(BIC)197和存 储器接口控制器(MIC)198。

本地存储器或本地储存器(LS)163-170是大的存储器映射的非 相干可寻址部分,其物理上可作为耦合到SPU 140-154的小存储器 而提供。本地储存器163-170可以被映射到不同的地址空间。在非别 名配置下,这些地址区域是连续的。本地储存器163-170通过它们的 地址位置而被关联到它们对应的SPU 140-154和SPE 120-134,例如 通过将在后文详细描述的SPU标识寄存器。只要本地储存器不是置 于安全操作模式,系统中的任何资源都有从/向本地储存器163-170 读出/写入的能力,在安全操作模式下,只有与其关联的SPU能够访 问本地储存器163-170或者本地储存器163-170指定的安全部分。

CBE 100可以是片上系统,使得图1中描述的每个元件可以在 单个微处理器芯片上提供。此外,CBE 100是异构处理环境,其中 每个SPU可以从系统中的其他SPU的每一个接收不同的指令。此外, 用于SPU的指令集不同于PPU的指令集,例如,PPU可以执行基于 精简指令集计算机(RISC)的指令,而SPU执行向量指令。在CBE 架构的另一方面中,PPU支持Power指令集架构(ISA)数据并行 SIMD扩展。

SPE 120-134经由EIB 196相互耦合并耦合到L2高速缓存器 114。此外,SPE 120-134经由EIB 196耦合到MIC 198和BIC 197。 MIC 198提供到共享存储器199的通信接口。BIC 197提供CBE 100 和其他外部总线和设备之间的通信接口。

PPE 110是双线程PPE 110。这种双线程PPE 110和八个SPE 120-134的组合使得CBE 100能够处理10个并发线程和超过128个 未完成的存储器请求。PPE 110作为处理大部分计算工作负荷的其他 八个SPE的控制器。例如,PPE 110可用于运行传统操作系统,而 SPE 120-124执行向量化的浮点代码执行。

SPE 120-134包括协同处理器单元(SPU)140-154、存储器流控 制单元155-162、本地存储器或储存器163-170和接口单元180-194。 在一个示例性实施例中,本地存储器或储存器163-170包括256KB 指令和对于PPE 110可见的并能够通过软件直接寻址的数据存储器。

PPE 110可以加载具有小规模程序或线程的SPE 120-134,将这 些SPE链接起来处理复杂操作的每一步。例如,包含CBE 100的机 顶盒可以加载用于读取DVD、视频和音频解码、以及显示的程序, 数据将会从SPE递送到SPE直到最终在输出显示上结束。在4GHz, 每个SPE 120-134给定理论上32GFLOPS的性能,其中PPE 110具 有相似级别的性能。

存储器流控制单元(MFC)155-162作为SPU到系统的其余部 分和其他元件的接口。MFC 155-162提供用于主储存器和本地储存 器163-170之间的数据传送、保护和同步的主要机制。逻辑上,处理 器中每个SPU都有一个MFC。在一些实施例中,可以在多个SPU 间共享单个MFC的资源。在这种情况下,对MFC定义的所有设施 和命令必须看起来独立于用于每个SPU的软件。共享MFC的效果 仅限于实现上相关的设施和命令。

利用图1的数据处理系统100,处理器106可能具有用于处理整 数(标量)和浮点(向量)指令二者以及在这两种数据类型上操作 的设施。然而,按照所述示例实施方式,处理器106可能具有用于 处理作为纯浮点SIMD指令和数据的SIMD指令和数据的硬件设施。 标量设施被用于整数处理,以及结合纯浮点SIMD架构用于其中的 循环控制和存储器访问控制。

图2是为了讨论示例实施例所做的改进的目的而展示的处理器 架构的框图。图2展示的特定处理器架构用于PowerPCTM970微处 理器,这可以从纽约Armonk的国际商业机器公司获得,详细的说明 在Gibbs等人的名称为“IBM eServer BladeCenter JS20 PowerPC 970 Programming Environment”的红皮书中,日期为2005年1月(可从 www.redbooks.ibm.com/redpapers/pdfs/redp3890.pdf获得)。

如图2所示,处理器架构包括指令高速缓存器202、指令取回单 元204、指令解码单元206和分发缓冲器208。指令取回单元204从 指令高速缓存器202取回指令,提供给指令解码单元206。指令解码 单元206解码指令,将解码的指令提供给分发缓冲器208。解码单元 206的输出提供给寄存器映射210和全局完成表212。寄存器映射210 映射到通用寄存器(GPR)、浮点寄存器(FPR)、向量寄存器文件 (VRF)等的一个或多个。然后,指令被提供到发布队列220-232中 适当的一个,这取决于通过指令解码单元206和寄存器映射210的 解码和映射而确定的指令类型。发布队列220-232向多个执行单元 240-258中的不同单元提供输入。执行单元240-258的输出去往多个 寄存器文件260-272中的不同寄存器文件。可以通过数据高速缓存器 280来获得与指令一起使用的数据。

特别值得注意,在所描述的架构中可以看到,处理器中针对浮 点、向量和定点、或整数、指令的存在单独的发布队列和执行单元。 如图所示,存在单个浮点单元(FPU)发布队列224,它有到两个浮 点执行单元244-246的两个输出端口,浮点执行单元继而具有到浮点 寄存器文件264的输出端口。单个向量置换发布队列226有一个到 向量置换执行单元248的输出端口,向量置换执行单元248继而具 有用于访问向量寄存器文件(VRF)266的端口。向量算术逻辑单元 (ALU)发布队列228有一个发布端口,用于向向量ALU 250发布指 令,向量ALU 250有用于访问向量寄存器文件268的端口。应当理 解,所有这些发布队列、执行单元和寄存器文件都占用资源、区域 和功率。

利用一些示例实施方式,在提供用于纯浮点SIMD架构的机制 时,这些发布队列224-228、执行单位244-250和寄存器文件264-268 被单个发布队列、执行单元和寄存器文件所代替。图3是示出根据 一些示例性实施方式的可选的处理器架构的示例性图示。图3中展 示的处理器架构是图2中所展示的PowerPCTM970架构修改后的形 式,因此,和图2中所展示的元件类似的元件使用类似的引用号码。 应该注意,示例的修改后的架构仅仅是一个例子,可以对其他处理 器架构进行类似的修改,以减少实施在这些其他架构中的发布单元、 执行单元和寄存器文件的数量。因此,示例实施方式的机制不限于 在PowerPCTM 970架构的修改形式中实施。

如图3所示,图3中修改后的架构用单个四处理执行单元(QPU) 发布单元310取代了发布单元224-228。此外,执行单元244-250被 单个四处理执行单元(QPU)320取代。此外,寄存器文件264-268 被单个四向量寄存器文件(QRF)330取代。因为四处理单元(QPU) 可以与单个指令并发地执行多达4个数据元素,因此这个修改后的 架构不仅降低了资源的使用、区域的使用,和功率的使用,而且简 化了处理器的设计,但是修改后的架构也增加了处理器的性能。

应该指出的是,在图3修改后的处理器架构中,仍然有处理标 量整数的定点单元(FXU)。此类标量整数主要用于控制操作,例 如循环迭代,等等。其他所有的指令都是浮点或向量格式。特别的, 与VMX指令集的混合的浮点和整数执行指令表不同,QPX指令通 常仅在浮点数据上操作,尤其是执行算术运算。整数型数据的此唯 一存储与数据到整数格式的转换相关联,此转换是出于加载和存储 这种整数、或者自和从浮点状态和控制寄存器(FPSCR)移动控制 字的目的。减少对纯浮点格式的操作极大地提高了浮点处理的效率, 因为可以选择针对浮点数的表示和处理而优化的适当的内部表示, 而不需要整数算术运算、逻辑操作以及其他类似操作。

按照一个示例实施方式,利用纯浮点SIMD ISA,不需要支持用 于存储比较结果、布尔运算、选择操作和数据对齐的整数编码,而 这在现有已知的ISA中是需要的。纯浮点(FP)SIMD ISA基本上允 许将所有数据存储成浮点数据。因此,图3中的向量寄存器文件330 中存储的数据类型只有一种。

按照一个示例实施方式,纯FP SIMD ISA提供比较浮点向量和 在向量寄存器文件330的浮点向量寄存器中存储比较结果的能力。 此外,纯FP SIMD ISA提供了用于选择操作和布尔运算的编码方案, 它允许使用浮点数据表示来执行选择操作和布尔逻辑运算。

在一个示例实施方式中,纯FP SIMD ISA使用具有四个元素的 纯FP双精度SIMD向量,也即,供QPU 320四执行的四向量。在 加载和存储操作期间,单精度SIMD向量被自动转换为双精度,或 者反之。尽管这里将描述的是双精度向量SIMD的实施,但示例实 施例不限于这个或其他精度,包括但不仅限于,单精度,扩展精度, 三倍精度,甚至十进制纯浮点SIMD,只要不脱离本示例的精神和范 围的都可以使用。

在一个示例实施方式中,用于实施纯FP SIMD ISA的示例实施 方式的机制主要提供作为QPU 320中的逻辑元件。在适当时,额外 的逻辑可以被提供到一个或更多的存储器单位LS1和LS2中。在其 他示例实施方式中,示例实施方式的机制可以作为在图3中展示的 修改后的架构中的其他元件中的逻辑来实施,例如,分布在多个图3 所示的元件上,或者在耦合到图3所展示的一个或多个元件的一个 或多个专用逻辑元件中。为了提供示例实施方式的实施的一个示例, 为了说明的目的假定示例实施例的机制作为QPU 320中的逻辑来实 施,除非另外指出。对于QPU 320的逻辑的一个示例实施方式的更 详细的解释,请参考附录A,其提供了对QPU 320架构的详细说明。

作为示例实施方式的纯FP SIMD ISA的一部分,提供比较FP 向量和在FP向量寄存器文件330中存储比较结果的能力。使用对应 于布尔值的FP值对比较选择进行编码。例如,在一个示例实施方式 中,对于“TRUE(真)”输出,也即,满足比较条件并且生成“TRUE (真)”结果,输出用FP值1.0来表示。对于“FALSE(假)”输 出,也即,不满足比较条件并且生成“FALSE(假)”结果,输出 用FP值-1.0来表示。基于比较条件满足还是不满足来生成这种FP 值的函数包括QVFCMPEQ函数、QVFCMPGT函数、QVFCMPLT 函数,QVFCMPEQ函数比较两个FP值以确定它们是否相等, QVFCMPGT函数比较两个FP值以确定第一个FP值是否大于第二个 FP值,QVFCMPLT函数比较两个FP值以确定第一个FP值是否小 于第二个FP值。此外,提供测试函数,如QVTSTNAN,以对“非 数字”(NaN)条件进行测试。这些函数的输出是对应TRUE(真) 的1.0或者对应FALSE(假)的-1.0。

除了这些比较函数,在示例实施方式的纯FP SIMD ISA中还提 供匹配选择功能。这一四向量浮点选择或QVFSEL函数具有格式 qvfsel QRT、QRA、QRC和QRB。利用这一四向量浮点选择功能, 在寄存器QRA的每个双字插槽中的浮点操作数与值0进行比较以确 定是“TRUE”或者“FALSE”值。如果操作数大于或等于0(即是 TRUE),则寄存器QRT的相应插槽被设为寄存器QRC的内容。如 果操作数小于零或者是NaN,则寄存器QRT被设为寄存器QRB的 内容。该比较忽略0的符号,即将+0.0视为等于-0.0。因此,这一匹 配选择函数的任何正的比较结果会导致QRT寄存器中的浮点SIMD 向量元素采用QRC寄存器中的对应浮点SIMD向量元素。否则,任 何负值或NaN值将导致QRT寄存器中的浮点SIMD向量元素采用 QRB寄存器中的对应浮点SIMD向量元素的值。

按照一个示例实施方式,输入和输出表示使用的TRUE和 FALSE的定义不同,其中输出表示(也即,生成的表示TRUE或 FALSE的值作为计算结果)是输入表示所使用的TRUE和FALSE 值范围的子集。具体地,使用表1所展示的表示:

表1-输入/输出表示

按照示例实施方式的一个方面,输入/输出表示的这一选择消除 了未定义的行为。按照示例实施方式的另一个方面,这一选择还提 供了“选择”函数与传统的基于根据至少一个传统指令集的浮点符 号的“选择”函数的兼容性,该传统指令集不提供存储以浮点数字 编码的布尔值以及执行比较和布尔操作的能力。按照示例实施方式 的另一个方面,当被用作读取布尔输入操作数的指令的输入时,这 一选择简化了布尔值的解码。

此外,利用示例实施方式的纯FP SIIMD ISA,还定义了四向量 浮点逻辑函数,从而生成向量输出。例如,针对纯FP SIMD ISA布 尔值来定义与(AND)、或(OR)、异或(XOR)、与非(NAND)等运算 的逻辑函数,例如,1.0表示TURE,-1.0表示FALSE。例如,纯FP  SIMD SIA定义了与(AND)运算,从而1.0AND 1.0产生输出1.0, 否则,和至少一个负操作数进行的AND运算的输出是-1.0。

一般地,按照本发明一个实施例的针对SIMD向量的每个向量 位置的示例性FP布尔AND的运算可以按表2描述:

  输入1\输入2   ≥±0.0   <±0.0或NaN   ≥±0.0   +1.0   -1.0   <±0.0或NaN   -1.0   -1.0

表2:FP布尔AND函数的示例性实施方式

类似地,对于或(OR)运算,纯FP SIMD SIA定义1.0 OR 1.0、 -1.0 OR 1.0和1.0 OR-1.0,从而产生1.0的输出,而-1.0 OR-1.0产生 -1.0的输出。

一般地,按照本发明一个实施例的针对SIMD向量的每个向量 位置的示例性FP布尔OR的运算可以按表3描述:

  输入1\输入2   ≥±0.0   <±0.0或NaN   ≥±0.0   +1.0   +1.0   <±0.0或NaN   +1.0   -1.0

表3FP布尔OR函数的示例性实施方式

同样地,按照上文中包含的教导和本发明的范围,本领域技术 人员基于已定义的一套TRUE和FALSE值的输入和输出表示将能够 定义其他的布尔函数。

按照本发明的一个示范性实施例,提供“flogical”指令。“flogical” 指令使用4位来编码“真值表”(也即,利用多达2个输入来编码 任意布尔逻辑函数),由此,两个被编码为浮点值的布尔操作数被 用于编入到该表的索引中并且获得布尔结果。然后,该布尔结果按 照示例实施方式的机制被编码为浮点(FP)布尔值,并被存储在寄 存器文件中。在SIMD向量架构的环境下,“flogical”指令是向量 “qvflogical”指令。在这一情形下,独立地使用每个插槽中的布尔值 来对每个向量位置独立地产生被编码为FP布尔的输出结果。

可以和上述图3所描述的SIMD架构一起使用的纯FP SIMD ISA 的进一步的说明,提供在和本申请共同受让和未决的申请号为 12/250,575的美国专利申请中,该申请名称为“Floating Point Only  Single Instruction Multiple Data Instruction Set Architecture”,申请日 为2008年10月14日,在此引入作为本申请的一部分。

再次参考图1,CBE 100中的SPE 120-134和/或PPE 110例如可 以使用图3中展示的纯FP SIMD架构,并且可以使用向量指令,如 SIMD指令。可选地,可以使用处理器使用具有向量元素的向量指令 的其他SIMD架构。因此,通过从源代码提取并行以及重新配置或 转换源代码以利用此并行,源代码可被编译器优化以在具有Power ISA或者纯FP SIMD ISA扩展的这些SPE 120-134或PPE 110上执 行。在分析源代码以优化和转换为SIMD向量化代码时,编译器可 能执行“如果-转换”操作。例如,可以使用如上文在前面讨论的数 据并行“如果-转换”机制和数据并行选择操作来执行这种“如果- 转换”。

如上所述,当代码被SIMD化时,也即,被向量化以用于在支 持SIMD的处理器上执行,在处理异常时产生问题,而这对于原始 预测代码通常不是问题。如上所述,预测代码指令或者会写入其结 果,因为这些指令生成单个结果,在这种情况下,结果被写入并且 如果适当的话引发异常,或者指令不会写入单个结果,在这种情况 下,结果没有被写入,并且不引发异常。然而,利用SIMD向量化 指令,这些指令可能生成多个结果,而不需要知道特定的结果会被 使用还是不使用,也即,一个值是预测性的还是不是,因此,不能 确定要生成的正确的异常集合是什么。因此,在已知的SIMD架构 中,或者启用异常,在这种情况下,可能会产生和处理虚假异常, 甚至在实际上不会被处理器执行的执行路径上产生和处理,也即, 执行的预测性路径,这导致浪费的周期;或者,在很晚后确定出现 问题时抑制异常,这需要用于调试机制的复杂的向回追踪操作。

然而,代替于归因于不能确定针对数据并行如果-转换的循环的 适当的异常集合而不得不抑制异常,利用示例实施方式的机制,示 例实施方式的机制提供了以数据流驱动方式的异常条件的按向量元 素追踪。利用这一按向量元素追踪,异常被作为特殊可识别字符或 者位模式而记录在向量元素中,该特殊可识别字符或者位模式可以 在稍后被用于生成异常,其关联的异常处理正在执行,例如,当确 定SIMD向量化代码的执行中选取了什么执行路径时。换句话说, 预测的执行路径上的异常被推迟到预测的执行的变为非预测时,例 如,引起预测性数据变为非预测性数据的存储指令或者移动指令。

此外,示例实施方式提供了传播和取代异常信息的能力。也就 是说,异常信息可能会被传播,直至确定了是否采取涉及该异常的 执行路径。如果采取了不同的执行路径,那么异常可能被取代,也 即,可能忽略特殊字符或者位模式,并且可能不会生成需要异常处 理的异常。另外,如果执行路径涉及向量元素,该向量元素中存储 有特殊字符或位模式,那么在确定了执行路径本质上不再是预测性 的时候,可以生成对应的异常并且执行异常处理。

例如,应该注意,利用数据并行选择操作,例如上面所述的, 数据并行选择操作组合来自多条路径的结果。数据并行选择操作不 选择具有指示异常值的特殊字符或位模式的向量元素,使得该异常 从该向量插槽的结果异常集合中消失。这样,基于数据流针对每个 向量插槽来传播异常。

此外,示例实施方式的机制提供了在向量元素中存储向量异常 信息和通过特定操作引发异常的能力,这些特定操作例如存储-和- 指示指令,和/或移动-和-指示指令,从而将执行转移到适当的异常 处理机。利用示例实施方式的这些机制,异常的识别基本上和异常 实际的处理分离开了,并且归因于该分离而提供了追踪这些异常的 机制。

在一个示例实施方式中,示例实施方式的机制利用浮点数的编 码来诊断和跟踪溢出条件和非法操作的异常。示例实施方式采用电 气和电子工程师学会(IEEE)的值来指示异常条件,例如,无穷大 表示溢出条件,NaN(非数字)值表示非法操作。在对应的异常发生 的情况下,这些IEEE值存储在向量元素中,而不是存储在数据元素 中。这些IEEE值继而作为向量元素进行传播,直到向量元素将要被 存留,例如,存储或者从一个寄存器移动到另一个寄存器。提供特 殊的存储-和-指示指令和/或移动-和-指示指令,以用于识别向量元素 中的这些特殊IEEE值以及生成对应的异常以供对应的异常处理机 处理因此,如果在执行流期间没有遇到这些存储-和-指示指令或移动 -和-指示指令,那么就不会生成这些异常。

利用示例性的机制,当编译器正在优化和转换代码时,编译器 执行数据并行如果-转换来实施SIMD ISA或者纯浮点SIMD ISA,这 通过将if指令翻译为数据并行选择操作来实现,也即,执行面向FP 的数据并行如果-转换。此外,当和向量元素关联的计算导致正在产 生异常时,编译器提供支持以在这种数据并行选择操作的向量元素 中存储异常值,也即,特殊字符或位模式。这些特殊字符、值或位 模式不会立即生成异常,而是如果对应于向量元素的执行路径、或 数据路径通过将其状态从预测状态转换为非预测状态来选择被存 留,则简单地指出异常可能已经生成以及应当在稍后生成。因此, 如果计算导致溢出条件,则对应的向量元素存储无穷大值、位模式、 或此类的,来指示如果跟随这一数据路径或执行路径,则将发生溢 出异常。此外,如果计算导致非法操作,则NaN值、位模式,或此 类的,被存储在相应的向量元素中以指示如果跟随这一数据路径或 执行路径,则将发生非法操作异常。例如,可以在图3中的QPU 320 中提供对存储这种值到向量元素而非数据值的支持。

图4A和图4B是说明按照一个示例实施方式的、在一个或多个 向量元素上操作的数据并行选择操作的示范图,其中向量元素具有 存储在向量元素中的异常值。图4A是实施数据并行选择操作的代码 的例子,而图4B是图4A中代码的图形表示,其示出按照示例实施 方式的作为代码中的指令的结果而生成的向量值和这些向量值如何 变化。在图4A所示代码的情形下,数据并行选择操作是指令 “QVFSEL”,它可以通过如上面所提到的编译器优化而被插入到代 码4A中。图4B说明数据并行选择操作可以如何传播示例实施方式 的特殊代码而不会导致抛出异常,以及可以如何使用数据并行选择 操作来忽略这样的条件,其中在代码的执行没有跟随执行路径或者 数据路径的情况下可能导致抛出异常。图4B进一步展示了这些在选 择的执行路径上的特殊代码是如何传播的,直到非预测性指令引起 这种特殊代码将要被存留到存储器、向量寄存器,或者此类的,其 继而引起异常被抛出和调用异常处理。在此共同参考图4A和图4B 来说明示例的操作。

应当指出,图4A和图4B中所展示的指令假定在预测状态下执 行,直到这些指令的结果被存留到存储器或者以其他方式作为非预 测性指令执行的一部分而被存留到其他的向量存储器。在这里提出 的示例的例子中,这样的非预测性指令包括存储指令和移动指令, 将在此后更详细讨论。

如图4A和图4B所示,针对SIMD向量化代码的这一部分,四 向量负载浮点数据(QVLFD)指令410加载向量QBI的第一组值, 它加载4个数据值到向量寄存器的4个插槽中。如图4B所示,在所 描述的例子中,用于QBI的被写入到向量寄存器的4个值是 {b0,0,b2,0}。通过执行QVFRE指令420得到值{1/b0,NAN,1/b2,NAN} 来生成4向量浮点的倒数值。非数字(NAN)值是由0的倒数生成 的,即1/0,这在IEEE标准中生成非数字值。通常地,当生成这种 NAN结果时,会报告错误,也即,抛出异常,这导致代码的执行被 分支到异常处理机,该异常处理机执行预定义操作以处理异常类型。 因为指令420的执行是预测性的,因此不能确保向量寄存器中的任 何一个NAND值都将实际上通过非预测性指令而存留到存储器或者 向量寄存器中,因此,分支到异常处理机会导致浪费的处理器周期 和资源。

然而,利用示例的机制,不是立即产生需要由异常处理机处理 的异常,而是暂时抑制或者延迟该异常,直到实际的异常值,此情 形下是NAN,被存留到存储器中,或者从一个寄存器移动到另一个 中,或者以其他方式被非预测性指令使用。因此,通过执行流简单 地传播异常值,直到该异常值被非预测性指令使用,在这种情况下, 抛出异常并调用异常处理。如果异常值从未被非预测性指令使用, 那么异常从不被抛出,也不会消极地影响执行流。

回到图4A和图4B所示的例子中,QVLFD指令410加载的向量 还被输入到四向量浮点比较(QVFCMP)指令430,该指令将向量插 槽中的值和零值向量(也即,{0,0,0,0})进行比较。基本上,QVFCMP 指令430确定加载的向量{b0,0,b2,0}中的值是否为非零。如果是这 样,则生成“真”值;否则,生成“假”值。在这一情形下,对向 量{b0,0,b2,0}中的每个向量值的“真”或者“假”值继而被存储到向 量{t,f,t,f}中。该向量与从QVFRE指令420输出的向量{1/b0,NAN, 1/b2,NAN}一起被输入到数据并行选择指令QVFSEL指令440。为 了提供缺省值,提供第三向量{d,d,d,d}作为QVFSEL指令440的输 入。

当由于QVFRE指令420而导致得到NAN值时,QVFCMP指令 430基本上生成用于屏蔽加载的向量{b0,0,b2,0}中的零值的屏蔽向 量{t,f,t,f}。也就是说,对于传播到QVFSEL指令440的向量{1/b0, NAN,1/b2,NAN}中的每个插槽,QVFSEL指令440确定是从向量 {1/b0,NAN,1/b2,NAN}中选择值,还是从缺省向量{d,d,d,d}中选择 缺省值。基于是否有“真”值出现在QVFCMP指令430的输出向量 的对应插槽中来进行确定,例如,本例子中是{t,f,t,f}。因此,作为 在三个向量{1/b0,NAN,1/b2,NAN}、{d,d,d,d}和{t,f,t,f}上操作的 QVFSEL指令440的结果,产生向量{1/b0,d,1/b2,d}。可以看到, 在执行流的这一点上,NAN值不再是问题。如果已经按照已知机制 基于QVFRE指令420的操作产生了异常,则异常处理可能已经导致 资源和处理器周期浪费在处理不会影响最终的计算机代码执行流的 异常条件,因为没有以任何方式使用异常值。如果这是代码的最终 输出,并且向量值{1/b0,d,1/b2,d}被非预测性指令使用,例如,通 过使用四向量存储浮点数据(QVSTFD)指令向存储器存留该向量, 则不会抛出任何异常,因此,避免了异常处理,因为非预测性指令 所使用的向量不包括指示需要处理的异常或者错误条件的任何特殊 异常值。

然而,在描述的例子中,向量值{1/b0,d,1/b2,d}不是最终的结 果,而是被加到加载向量{c0,c1,NAN,c3}的另一个四向量负载浮点 数据指令450的输出中。四向量相加(QVADD)指令460把向量{c0, c1,NAN,c3}加到向量{1/b0,d,1/b2,d}上,产生向量输出{1/b0+c0, d+c1,NAN,d+c3}。这一向量输出被提供给非预测性四向量存储浮点 数据(QVSTFD)指令470,该指令470把该向量输出{1/b0+c0,d+c1, NAN,d+c3}存留到存储器中。因为非预测性指令470现在正使用具 有特殊异常条件值NAN的向量,因此,报告错误,也即,抛出异常, 这导致执行流被分支到用于处理错误条件的例行程序,也即异常处 理机。因此,虽然QVFRE指令420输出中的NaN值没有导致QVSTFD 指令470收到的最终输出的异常,但是在QVLFD指令450的输出中 的NaN值导致异常值沿着执行流被传播到非预测性指令470,从而 导致将抛出推迟的异常。

如上所述,在公知系统中,一旦QVLFD指令450产生NAN结 果,就会立即抛出异常,并且可能已执行将执行分支到异常处理机。 然而,在示例中,传播NAN值直到它或者被取代,如在所描述的 QVFSEL指令440的情形下那样,或者被非预测性指令所使用,由 此导致抛出异常。这允许推迟对异常的处理直到确定异常处理是必 要的为止,并且允许在异常不影响执行流的情况下取代异常。

再次参考图3,应当理解,上面描述的存储器向量操作,例如加 载和存储,可以被图3中的加载/存储单元LS 1254和LS2258执行 以从向量寄存器文件330写入和读取值。其他非存储器向量操作, 例如计算或者此类的,可以通过具四处理单元(QPU)发布单元310 和QPU 320来执行,其中结果被写入向量寄存器文件330。编译器 可以优化和SIMD向量化计算机代码,以使得利用推迟的异常处理 来传播异常值的机制在经编译的代码中执行,该代码通过图3中的 处理器架构的机制来执行。

因此,代替于产生异常以及不得不处理这些在程序执行实际上 未跟随的执行路径中的异常,示例的机制将异常条件的识别从异常 的实际处理中解耦合出来,使得只有那些程序的执行流实际上遇到 的异常条件实际上被处理。结果,处理器周期不再浪费于处理实际 上不影响程序执行的异常。

为了提供这一解耦合,如上所述地,提供对响应于检测到异常 条件而在向量元素中设置特殊值的支持。此外,提供用于识别这种 特殊值以及产生适当的异常的特殊指令,假若在程序执行期间遇到 向量元素中的这些特殊值,也即,假若涉及该向量元素的数据路径 或执行路径被选择,诸如通过数据并行选择操作。在一个示例中, 这些特殊值是存储-和-指示指令和移动-和-指示指令。当优化和转换 用于SIMD向量化执行的代码的原始部分时,编译器可以用这种存 储-和-指示操作或移动-和-指示操作来取代代码的此原始部分中正 常的存储或移动指令。

虽然在示例中使用了存储-和-指示指令和移动-和-指示指令,但 是应当理解示例不限于此。而是,任何非预测性指令都可以具有该 非预测性指令的对应X-和-指示的版本,其中“X”是由非预测性指 令执行的操作。存储-和-指示和移动-和-指示指令仅仅是此类可以根 据示例实施方式用于提供异常指示的非预测性指令的例子。

图5是说明根据一个示例的存储-和-指示指令的示例图。如图 5所示,存储-和-指示指令,其在图5中表示为四向量存储浮点单索 引和指示指令,确定四向量寄存器QRS的向量元素中的字节指示非 数值(NaN)值还是无穷大(Inf)值。图5中需要特别注意,四向 量存储浮点单索引和指示指令包括代码31,该代码31被处理器架构 用于将指令识别为四向量存储浮点单索引和指示指令、四向量寄存 器输入向量QRS,和标量寄存器RA和RB的标识符,标量寄存器 RA和RB保持用于计算指令结果的有效地址的值。

在描述的例子中,四向量寄存器QRS的第一向量元素对应于字 节0:7,第二向量元素对应于字节8:15,第三向量元素对应于字节 16:23,第四向量元素对应于字节24:31。如果这些向量元素的任何一 个指示NAN值或者INF值,则指示QPU异常。应当注意,虽然图 5中示出的是存储-和-指示指令,但也可以提供类似的移动-和-指示 指令,其执行针对向量元素中的NAN和INF值的这种检查。

如图5所示,仅在对应值QPU_enable_indicate_NaN或者 QPU_enable_indicate_Infinity被设为适当的值时,才执行这些检查。 这些值可以在图3中QPU 320的适当的控制寄存器中被设置,例如, 在这些控制寄存器中的值可以指示QPU320是否要监控NaN或者无 穷大值以及使用它们来追踪异常。仅当这些值在控制寄存器中被设 置时,图3中的QPU 320才会实际上执行如下功能,利用存储-和- 指示指令或移动-和-指示指令在向量元素中存储指示异常条件的特 殊异常值,并且执行对于这些向量元素中的特殊值的检查。

图6是根据一个示例的编译器的示范性框图。如图6所示,编 译器610接收原始源代码620,编译器610被配置用于根据示例实施 方式对原始源代码620进行分析。也即,编译器610识别源代码620 中具有可被修改以用于SIMD或者纯FP SIMD向量化执行的条件控 制流的循环的那部分。源代码620的这种部分可以通过利用数据并 行选择操作的数据并行“if”转换来进行转换,其中数据并行选择操 作实施示例实施方式的机制,以在向量元素中存储异常条件值,并 且仅当对应于向量元素的数据路径或者执行路径被选择并且向量元 素的值被存储或移动时,生成异常。编译器610可以利用识别向量 元素中的这种异常条件值和相应地生成指令的存储-和-指示指令和/ 或移动-和-指示指令来代替原始源代码620的存储和/或移动指令。 在其他示例中,其他类型的非预测性指令可被这些被修改以支持X- 和-指示类型的操作的对应版本所代替,在X-和-指示类型的操作中, 非预测性指令执行其正常操作,但继而还提供在架构中启用的并且 被发现存在于对X-和-指示类型的指令的输入中的任何异常条件的 指示。

编译器执行的优化和转换的结果是实施示例实施方式的优化和 转换的经优化/转换的代码630。然后把经优化/转换的代码630提供 至链接器640,链接器640如在本领域中公知的那样执行链接器操 作,由此生成可执行代码650。可执行代码650然后被处理器660 执行,处理器660可以是图1中CBE 100或者别的数据处理系统架 构中的处理器。

应当指出,存在异常条件可能丢失或者异常条件可能先于存储- 和-指示指令或者移动-和-指示指令的执行而改变的情形。可以在图3 的QPU 320中提供测试,用于在期望时测试这些条件。例如,在输 入具有无穷大值(INF)的向量元素但是计算的输出是“0”时,条 件可能发生。如果需要检测这种条件,则QPU 320可以检查溢出条 件的除数,也即,QPU 320可以具有用于检查用于Inf(无穷大)的 特殊值的除数寄存器的逻辑。如果检测到这种特殊值,那么当程序 执行遇到这种条件时,仍然能够生成溢出异常。图7A是说明根据一 个示例的可以执行针对除法寄存器上的溢出的测试以检测丢失异常 条件的条件集合的示例图。如图7A所示,当除数具有“INF”值并 且操作数是-1、-0、0或者1时,出现此条件。

异常可能丢失的另一条件这样的条件,在该条件下,溢出条件 (IFN)被转换为非法的操作条件(NAN)。当计算涉及INF-INF、 0*INF、或者此类的其他类型的计算时,发生这种情形。很多时候, 只检测到存在异常就足够,并且异常是溢出异常还是非法操作异常 并不重要,例如,当通过对控制寄存器值QPU_enable_indicate_NaN 和QPU_enable_indicate_Infinity的设置来启用两种类型的异常时。 然而,在其他情况下,例如当仅启用一个类型的异常时,在异常类 型之间进行区分可能是重要的。在这种情形下,测试溢出异常可以 被转换为非法操作异常的条件是重要的。

如果需要这种测试,QPU 320可以提供有针对溢出值检查操作 数和/或除数寄存器的逻辑。图7B是说明根据一个示例的可以执行 针对操作数寄存器上的溢出的测试以检测溢出-到-NAN的变化条件 的条件集合的示例图。如图7B所示,对于加法运算或减法运算,可 以针对溢出条件检查操作数和除数寄存器的值。如果两个都具有INF 值,那么可能生成溢出异常,而不是以其他方式指示的非法操作异 常,如图7B所示。此外,对于乘法运算,如果除法寄存器是溢出值 并且操作数寄存器具有0值,那么可能生成溢出异常,而不是以其 他方式指示的非法操作异常。同样地,对于除法运算,如果除法寄 存器具有溢出值并且操作数寄存器具有溢出值,那么可能生成溢出 异常,而不是以其他方式指示的非法操作异常。

图8是概述根据一个示例的用于设置向量元素的值的示例操作 的流程图。如图8所示,操作开始于在目标向量的向量元素上执行 操作(步骤810)。确定在计算期间是否遇到了异常条件(步骤820)。 如果没有,则将计算的结果数据值存储在向量元素中(步骤830)。 如果遇到了异常条件,那么对应于该异常条件的特殊异常值被存储 在向量元素中,而不调用异常处理机(步骤840)。根据所使用的指 令集架构,该特殊异常值通过处理器架构在向量元素中传播直到遇 到存储/移动操作为止,或者直到该特殊异常值被取代为止(步骤 850)。应当注意到,在某些情形下,特殊异常值的传播可以包括取 代这一值使得异常值基本上不出现在执行流中。例如,如上讨论的, 在如上图4A和图4B的例子所描述的数据并行选择指令在屏蔽异常 条件或者非预测性指令不使用异常值的情形下,导致异常值停止传 播。

在以向量元素出现在其中的向量为目标的计算机程序的执行期 间,确定是否遇到非预测性指令的确定(步骤860),非预测性指令 如存储-和-指示指令或者移动-和-指示指令。如果没有,则忽略异常 条件(步骤880)。如果遇到了存储-和-指示指令或者移动-和-指示 指令,那么生成异常并将其发送给异常处理机(步骤870)。操作然 后结束。

图9是概述根据一个示例的用于生成异常的示例操作的流程图。 如图9所示,操作开始于在向量上执行存储-和-指示指令或者移动- 和-指示指令(步骤910)。确定控制寄存器是否有对应的 enable_indicate_NaN值的集合(步骤920)。如果有,则确定向量中 的任一向量元素是否具有NAN值(步骤930)。如果有,则生成非 法操作异常,并且发送到适当的异常处理机(步骤940)。

否则,或者如果enable_indicate_NaN值没有设置在控制寄存器 中,则确定enable_indicate_Inf值是否设置在对应的控制寄存器中(步 骤950)。如果是,则确定向量中的任一向量元素是否具有INF值(步 骤960)。如果是,则生成溢出异常并且执行分支到对应的异常处理 机(步骤970)。此后,如果向量元素不具有Inf值,或者如果enable- _indicate_Inf值没有设置在控制寄存器中,则向量被存储/移动(步 骤980),并且操作结束。

应当看到,NAN和INF值仅仅用作可以被示例实施方式的机制 使用以识别可能需要异常处理的异常条件的特殊异常值的例子。对 于任何其他类型的可以被用来指示在指令的预测性执行期间已经遇 到的异常条件的特殊指示符值,可以执行类似的操作而不脱离示例 的精神和范围。

因此,示例提供了用于检测异常条件和传播特殊异常值而不立 即调用异常处理机的机制,其中该特殊异常值将异常条件指示作为 向量的对应向量元素的一部分。仅当特殊异常值作为计算机程序的 执行的一部分而实际上遇到时,生成对应的异常并将执行分支到异 常处理机。这样,异常条件的检测和异常的处理相互解耦合,以允 许忽略不是计算机程序所采用的实际执行路径的一部分的执行分支 中的异常条件。示例的机制允许SIMD化代码以启用异常,同时最 小化不被计算机程序的执行路径实际上跟随的执行分支中的虚假异 常和异常处理。

如上描述的示例具有编译器,其把现有的存储或移动指令转换 为存储-和-指示指令或移动-和-指示指令。然而,应当理解,编译器 把每个存储或移动指令转换为存储-和-指示指令或移动-和-指示指 令并不是必需的。相反,根据进一步的示例,编译器可以提供有用 于在代码中选择适当的要将存储或移动指令转换为存储-和-指示指 令或移动-和-指示指令的位置的逻辑。此外,如上所述,示例不限于 仅存储-和-指示指令或者移动-和-指示指令,除此之外,编译器可以 利用任意X-和-指示类型的指令,其中X是要执行的操作,例如,加 法-和-指示,或者此类的。因此,当编译器把源代码,例如标量码转 换为SIMD向量化代码时,编译器可以基于编译器内提供的逻辑针 对这种X-和-指示类型的指令选择适当的位置。

利用示例的机制,在将源代码,例如标量码,转换为SIMD向 量化代码时,例如移动-和-指示、存储-和-指示、或此类的(共同被 称为“指示”指令)X-和-指示指令被插入到源代码的适当的位置, 以利用特殊值来识别异常条件的出现。编译器根据一个或多个方法 来确定适合的插入点,该方法基于感兴趣的值是可检查还是不可检 查的,这将在下文定义。在一个方法中,SIMD代码中不可检查的部 分可以通过使用屏蔽机制转换成可检查的SIMD代码。在一个方法 中,指示指令可以被插入在每个涉及感兴趣的值(例如,感兴趣的 值的数组)的计算之后。在另一个方法中,最少数目的检查指令被 插入到适当的位置以测试每个活的输出值,其中如果值最终影响了 存储镜像或者代码的判决过程(或者连续的计算将使用该结果以最 终影响存储镜像或者代码的判决过程),则该值是活的。

为了说明当确定在被编译器优化和编译的代码的何处中插入这 种X-和-指示指令时可以被编译器利用的逻辑的示例,首先描述逻辑 的总体流程,在这一流程中略述的每个操作的将在此后描述。应当 理解,流程和此后的详细描述仅仅是可以被用于插入X-和-指示类型 的指令的逻辑的示例,其他逻辑可被实施示例的机制的编译器使用 而不脱离示例的精神和范围。

图10是概述根据一个示例的用于由编译器将指示指令插入到 SIMD向量化代码中的示例操作的流程图。图10的操作假定对于将 要被编译器检查的代码的给定部分,编译器已经生成了相关性图。 该代码部分可以是基本块、语句、表达式、或者编译器可在其上操 作的任何其他的工作单元或代码。对于将要被编译器检查的代码部 分由编译器生成相关性图,是本领域中的公知的,因此,在此不提 供详细的描述。如本领域所公知的,相关性图包括节点和节点间的 弧,其中,弧表示代码各部分之间的相关性,例如依赖于其他指令 的指令。

如图10所示,对于要被编译器检查的工作单元,确定需要被编 译器检查的一组值(步骤1010)。对于需要被检查的每个值,分析 相关性图以确定相关性图中提供等同覆盖的一组位置(也即,节点), 等同覆盖也即可以执行检查的位置,这等同于在涉及该值的图的每 个节点上检查(步骤1020)。

例如,考虑计算“c[i]=(a[i]+b[i])+1”,其中想要检测非数值 (NAN)异常。要做到这一点,必须检查a[i]生成的输入值不是NAN。 因此,可以检查从存储器中加载a[i]值到寄存器文件的加载操作的结 果。然而,假设添加一个数到NAN值也生成NAN,则检查“a[i]+b[i]” 的结果提供了等同覆盖(从检查a[i]是否生成了NAN的观点来看)。 事实上,检查“a[i]+b[i]”是更有益的,因为,它还检查了b[i]的值 是否是NAN。引申开来,为了检查a[i]的值,检查如下的位置是等 效的:“a[i]”、“a[i]+b[i]”、“a[i]+b[i]+1”。在这些情形下,虽 然所有的这些位置是等效的,但是明显更有利的是检查第二或第三 位置,因为它还检查了“b[i]”的值。检查最后的位置是最便宜的, 因为可以将计算的“a[i]+b[i]+1”的值到存储器位置“c[i]”的存储 转换为存储-和-指示。

当工作单元大于语句时,可能存在横跨多个语句的若干等效位 置。考虑语句“c[i]=(a[i]+b[i])+1”,其后无条件地跟着另一个语 句“d[i]=c[i]+e[i]”。在这种情况下,可以添加“c[i]”和“c[i]+d[i]” 作为等效位置以检查a[i]是否是NAN。

确定这些识别的位置中的一个或多个是否能够被检查(见下文 中的“可检查的”值和位置的定义)(步骤1030)。如果是,选择 这些可检查的位置中的最佳的一个(步骤1040)。

如果在识别的位置中没有可检查的位置(步骤1030),那么确 定是否存在可以被转换成可检查形式的一个或多个位置(步骤 1050)。如果是,选择对于这种检查的最佳位置(步骤1060),并 且,转换该位置使得该位置的不可检查部分与可检查部分相分离, 例如,通过屏蔽具有安全值的位置处的输出寄存器的寄存器值的不 可检查部分、执行循环脱皮、或者此类的(步骤1070)。在操作1040 或者1070之后,操作-和-指示指令(也简单地称为“指示”指令) 被插入到选择的位置(步骤1080)。此指示指令实质上检查指示异 常条件的特殊值,该异常条件由于先前的计算可能已经发生,但是 这种异常处理根据前面描述的方式被推迟。如果存在这种特殊值, 那么通过X-和-指示指令来指示异常,并且可以启动异常处理。

如果没有可检查的位置并且如果没有可以被转换以使得部分是 可检查的位置,那么对应于该值的值计算被标记为标量(步骤1090)。 确定工作单元中的其他值是否需要检查(步骤1095)。如果是,操 作转到步骤1020,并且针对下一个选择的值,重复该操作。否则, 操作结束。注意,在上述实施例中,步骤1050确定是否存在至少一 个可转换的位置。当是这种情形时,代码将被转换以使得该代码是 可检查的。在又一实施例中,步骤1050还检查代码是否可被有利地 转换。实际上,可能存在转换SIMD代码以使得它是可检查的所附 加的成本超出了SIMD化该语句的益处的情形。在这些情形下,简 单地选择进行到步骤1090而不是将代码转换为SIMD代码,可能是 更有利的。

如上面所描述的,当确定在何处插入指示指令时,由编译器进 行的一个原理性确定是确定相关性图中的什么位置是可检查的或不 可检查的。在确定相关性图中的位置是“可检查的”还是不可检查 的时,编译器查找存储有相关性图中的位置的得到的SIMD向量输 出值的寄存器,并且确定存储在该寄存器中的值是“可检查的”还 是不是。如果满足以下一个条件,则向量寄存器的插槽中的值是可 检查的:(1)如果它包括活的浮点值并且该值实际上被计算过;或 者(2)如果已知该值具有保证不会引起异常的浮点表示。对于上面 的(1),如先前所提到的,如果浮点值最终影响存储镜像,也即存 储在存储器中的数据,或者影响代码的判决过程,例如,影响在代 码的执行期间选择哪个执行分支,则该浮点值是“活的”。作为替 换,如果连续的相关的计算使用这一值并且该计算影响存储镜像或 者判决过程,那么该值也被认为是“活的”。该值还必须是实际上 被计算出的,也即,不是拷贝或者移动到寄存器,而是实际上就是 计算的结果。例如,这排除了简单地从存储器中读出以被结合到计 算中的数据。

对于上面的(2),用户或者编译器可能规定某些值保证不会引 起异常。例如,编译器可以将某些大值的集合设为零。在这一情形 下,编译器可以指示对于这种大值的集合,零值不会引起异常。因 此,如果这种值是在SIMD向量寄存器的插槽中,则这一值可以被 认为是可检查的。类似地,用户可以规定某些值不会引起异常,并 且,当遇到这些值时可以同样地是可检查的。例如,计算可以包括 来自装有已知值的小的系数表的数据。例如,计算可以重复使用sin(x) 的值,其中x是10度的倍数。用户可以事先计算sin(0), sin(10),...,sin(350)的值,将这些结果存储在小的数组中,并且然后读 取这些数组值,而不是每次都计算sin(x)。因为用户已经完全掌控了 这张表,并且知道它的值在-1.0到+1.0之间,因此用户可以向编译 器断言(通过指示、附注、编译器标记、或者向编译器交换信息的 其他方式),该表保证不会是NAN值、负无穷大、或正无穷大。

如果SIMD向量寄存器的每个插槽存储可检查的浮点值,也即, 浮点值是“活的”且实际上计算出的,或者是已知不会产生异常的, 那么SIMD向量寄存器本身被认为是可检查的。例如,在先前讨论 的例子的架构中,每个SIMD向量寄存器由4个插槽或值组成。在 这种架构中,4个插槽中的每一个必须存储在前面描述的可检查的定 义下的可检查的值。

图11A-图11C是说明根据一个示例的标准的可检查和不可检查 的SIMD代码部分之间的区别的示例图。在第一个例子中,如图11A 所示,正在被编译器检查的工作单元或者代码部分是语句 “d[i]=(a[i]>0.0)?b[i]:c[i]”。这一语句得到的相关性图在图11A中示 出,正如编译器在以本领域公知的方式执行这一语句的编译时所生 成的。然而,根据示例实施例的机制,相关性图的节点可能被分类 为关于工作单元(也即,在此示例中正在被编译器检查的语句)的 值为可检查的和不可检查的两种。

如图11A所示,由于值a[i]影响代码的判决过程,也即,基于 a[i]和值“0.0”的比较,SIMD代码中的“选择(select)”操作,在 相关性图的部分1120中的指令的输出是可检查的。基本上,a[i]和 0.0的比较进行了屏蔽,在其中,如果屏蔽值的是1,那么选取第一 个值,例如b[i];如果屏蔽值的是0,那么选取第二个值,例如c[i], 这通过随后的“select”指令进行。结果,在存储指令st d[i]中的值 被值a[i]所影响,因此,它是活的并且实际上是通过选择指令计算出 的。

另一方面,相关性图的部分1110中的加载b[i]和c[i]的加载指 令的输出是不可检查的,因为不能保证这些加载的结果实际上将以 任何方式使用。已知通过这些加载生成的一个值将会被使用,但是 在编译时间,编译器不可能知道将会使用哪一个值,也即,在执行 期间的任意时间可能使用还是不使用b[i]还是c[i]。因此,这些值在 它们的当前状态下是编译器不可检查的。

作为进一步的例子,考虑语句d[2i]=a[i]+b[i],图11B为其示出 了相关性图1125和用于SIMD向量寄存器d[i]1130的插槽的寄存器 值。如图11B所示,在此处提供的可检查的定义下,相关性图1120 的部分1140是可检查的,但相关性图1120的部分1150是不可检查 的。部分1140是可检查的,这是因为已知值a[i]和b[i]将被使用以 影响存储指令st d[i]存储的值,也即,它们是活的,并且用于影响存 储在存储器中的值d[i]的这些值是被相加(add)指令计算出的。部 分1150是不可检查的,因为不能保证在存储d[i]时将使用加载指令 ld d[i]的所有结果。这展示在向量寄存器d[i]1130的例子中,其中, 插槽0中的第一个值是a[0]+b[0]的值,此处i=0;插槽1中的第二个 值是被ld d[i]指令加载到此插槽中的原始d[i]值,因为,当i=1,语 句的值是d[2]=a[1]+b[1],并且因此,插槽d[2]的值被更新以存储值 a[1]+b[1]。同样地,对于插槽d[3],存储的值是被ld d[i]指令加载的 原始值。因此,解包(unpack)指令组合了通过ld d[i]指令加载的值 (不实际上计算这些值而是仅加载它们)和基于来自相加指令的向 量a[i]和b[i]所计算的值。由于有些值是可检查的,有些值是不可检 查的,因此,根据所有的插槽都必须存储可检查值的可检查寄存器 的定义,解包指令的结果是不可检查的。结果,存储指令st d[i]是不 可检查的。但是,这可能发生变化,如果确定由指令ld d[i]加载的 d[i]中的所有值都是保证不会产生异常的值的话。

图11C提供了根据示例的可检查和不可检查的SIMD代码的又 一个例子。图11C所示出的是语句for(i=0;i<65;i++)a[i+2]=b[i+1]+ c[i+3]的例子,这是一个读取-修改-写入操作。如图11C所示,输入 向量是a[i]、b[i]和c[i],其中向量值a[i]被从存储器1160中读出, 被加法b[i+1]+c[i+3]修改,然后被写回到存储器1160。由于在这个 例子中SIMD架构运行在具有4个插槽的向量上,当读取-修改-写入 操作的对象是值a[2]时,执行向量加载操作1162以取回对应于a[2] 的值。这包括从存储器1160读取值[a0,a1,a2,a3]。a[2]的值对应于 在上述语句中i=0的值,该语句被求值以存储值[*,*,b1+c3,b2+c4]。 这两个向量被输入到选择操作1164,该选择操作针对输出向量寄存 器1166的每个插槽选择由向量加载指令1162所加载的原始值,或 者选择该语句所计算的新值。在这一情形下,因为操作是在值a[2] 上的读取-修改-写入操作,因此原始值a0和a1被选择用于输出向量 寄存器1166的前两个插槽,计算的值b1+c3和b2+c4被选择用于输 出向量寄存器1166的最后两个插槽。

原始值a0和a1是不可检查的,因为编译器事先不知道这些值 是否将被实际上使用,并且这些值不是实际计算出的而是仅从存储 器加载的。因此,在上文和下文的定义中,这些值a0和a1不是“活 的”,不是可检查的。另一个方面,计算的值b1+c3和b2+c4是可 检查的,因为它们是被计算出的,并且影响存储镜像,因此它们是 “活的”。

如上所述,对于要成为可检查的SIMD向量寄存器,存储在向 量寄存器的插槽中的所有值必须是可检查的。因此,输出向量寄存 器1166不是可检查的,因为输出向量寄存器1166的至少一个值是 不可检查的,也即,存储值a0和a1的插槽是不可检查的。然而, 对于向量存储指令1170来说,其值正被写入到存储器1160中的向 量寄存器是可检查的,因为向量寄存器中的每个插槽存储根据该语 句计算出的值,因此,存储了“活的”值。

回到图10中概述的操作,如上面所提及的,该操作确定提供等 同覆盖的位置。在这些位置,确定是否这些位置的任何一个是可检 查的,也即,对应指令的输出寄存器的是可检查的还是不可检查的。 在进行这一确定时,上面说明的标准可以被编译器的逻辑利用以确 定对应指令的输出寄存器是可检查的还是不可检查的。编译器可以 使用这种标准来分析每个识别的位置并且确定哪些位置是可检查 的。

如图10所示,如果没有位置是可检查的,则确定这些位置的任 何一个是否能够被转换为可检查的位置。大体上,这一确定是这样 的确定,其中分析输出寄存器以确定输出寄存器中任何一个插槽是 否是可检查的。如果是,那么输出寄存器中可检查的插槽被识别, 并且可以生成掩码(mask)以屏蔽该输出存储器中不可检查的插槽。 通过用已知不会生成异常的值(例如,0值或者其他的不生成异常的 安全值)来取代这些值,该输出存储器中不可检查的插槽可以被屏 蔽。在执行由插入的X-和-指示指令执行的检查操作之前,可以应用 掩码,这将在下面描述。掩码可应用于X-和-指示指令的操作的目的。 然而,这一屏蔽动作不改变应用的行为(除了通过X-和-指示操作生 成可能的异常之外),因为之后被编译器用于其计算的寄存器的值 没有改变。换句话说,对于要被检查的寄存器,在不同的只会被X- 和-指示操作使用的向量寄存器中,不可检查的值被屏蔽(通过用安 全值取代它们)。如果该检查通过存储和指示操作完成,那么该被 屏蔽值被存储到从不被原始程序读取的存储器位置中。例如,可以 仅为这一目的保留存储器栈上的存储器位置。如果使用移动-和-指示 操作,那么例如定位在寄存器Y中的屏蔽值可能被移动到同一寄存 器Y(或者当前不使用的任何其他寄存器)。不论何种操作,目的 是以当前没有被应用使用的存储器或者寄存器为目标,因此,不会 以任何方式改变应用的行为(但是归因于异常检查到的NAN、无穷 大、或其他值的存在可能产生异常)。因此,以此方式,出于插入 X-和-指示指令的目的,其他的不可检查的位置可以被转换成可检查 的位置。

再次,如图10所示,如果存在至少一个可检查位置,或者至少 一个位置能够被转换成可检查位置,则执行对用于插入X-和-指示指 令的最佳位置的选择。对用于插入的最佳位置的选择取决于期望的 异常覆盖的特定级别。也即,在异常覆盖的第一级别中,实现没有 虚假异常的低开销,但是只实现部分异常覆盖,也即,只提供了下 溢和上溢条件的部分检测,而没有提供NAN条件的完全覆盖。在异 常覆盖的第二级别中,也实现没有虚假异常的较高开销,但实现了 全部异常覆盖。在异常覆盖的第三级别中,异常覆盖的上述两种级 别都实现了,并且可能的虚假异常在软件中校正。下文参考图12A- 图12C和图13A-图13C,更详细地描述根据异常覆盖的这三个级别 的每一个,对用于X-和-指示指令插入的最佳位置的选择。

图12A-图12C是说明根据一个示例的用于插入指示指令的插入 位置的示例图。在这一示例中,使用异常覆盖的第一级别,也即, 其中仅部分异常覆盖。利用这一示例,插入最少数量的X-和-指示指 令以测试每个活的输出值。作为示例的一部分,选择用于插入X-和- 指示指令的最佳位置包括,在检测计算中的每个可检查向量寄存器 之后,检测测试被这一计算所计算出的每个活的输出寄存器值的最 小数目的位置,以及插入对应的X-和-指示-指令,例如,存储-和- 指示、移动-和-指示、相加-和-指示,或者对应于在该识别的位置的 指令的其他X-和-指示指令。

对用来测试每个活的输出寄存器值的位置的最小数的选择可能 包括,例如,选择一个或多个可检查位置,使得在没有正被X-和- 指示指令检查的情形下,没有进一步的计算可以到达存储指令。期 望尽可能早地在工作单元的执行中或者在最小量的附加开销成本的 点处捕获这种值。当工作单元中存在多个语句,例如,当编译器在 基本块或此类上操作时,这可能被进一步放松。例如,假定编译器 正在基本块上工作,该基本块包括设置包括为向量a[i]设置值的指 令,例如a[i]=...,和使用此向量值a[i]的指令,例如,...=...a[i]...。 在此情形下,编译器只需要在对应第二指令的位置处插入X-和-指示 指令,这是因为,存储了指示异常的特殊值的第一指令中的a[i]暗示 了在第二指令中的a[i]也产生指示该异常的特殊值,例如,第一指令 中的NAN值引起第二指令中的NAN值。

再次参考图12A-12C,图12A说明了根据异常覆盖的第一级别 的X-和-指示指令插入的第一个例子。此第一个例子关于语句d[i]= (a[i]>0.0)?b[i]:c[i]。如图12A所示,在先前定义的标准下,部分 1210是不可检查的,部分1220是可检查的。可以被插入的X-和-指 示指令检查的所有活的输出值的相关性图中的最早的插入位置是在 存储指令st d[i]处该最早的插入位置。也即,相关性图中的第一个节 点被选择,其中工作单元(在这一情形下是语句)中所有的活的值 在选择操作之后,在该选择操作中,活的值被用于修改存储镜像。 因此,在这一情形下,存储-和-指示指令可以被插入到存储节点位置 以取代原始存储指令。注意,在这一例子中,还必须检查可能的NAN 数的“a[i]”的值。进行这一检查的原因在于比较操作(诸如此处的 大于或“>”)被定义为在其任何一个输入是NAN,返回假(false) 值。因此,如果没有检查“a[i]”值中的异常,那么如果在向量寄存 器的给定插槽中存在NAN值,则对该插槽将总是选择“c[i]”的值。 因为“c[i]”的值不可能是NAN,因此在正在执行存储和指示时对 “c[i]”值的检查不会显示出现在“a[i]”值中的NAN。因此对于这 一例子,必须针对NAN检查“a[i]”值。

图12B说明对于示例语句d[2i]=a[i]+b[i]插入X-和-指示指令 的第二个例子。在如上规定的这些条件的定义下,对于该语句的相 关性图中的部分1230是可检查的,部分1240是不可检查的。在这 个例子中,相关性图中可以检查所有活的值的第一个位置在相加指 令处。结果,相加-和-指示指令可以被插入到这一节点以取代原始的 相加指令。在缺少相加-和-指示指令的平台下,可以使用附加的移动 -和指示,其中保存有该加法的结果的寄存器被移动到另一个未使用 的寄存器(它将不会在随后使用),这仅限于在加法操作的结果上 使用指示操作的目的。同样地,还可以使用存储-和-指示以将加法的 结果存入到未使用的存储位置,这同样仅限于在加法操作的结果上 使用指示操作的目的。

图12C说明对于示例的包括语句d[2i]=a[i]+b[i]和e[i]=d[i]+ 1.0的基本块插入X-和-指示指令的第三个例子。如图13C所示,对 于基本块中的第一个语句的相关性图与图13B所展示的是相同的, 因此,它具有同样的可检查部分1230和不可检查部分1240。对于第 二个语句的相关性图是完全可检查的。但是,代替于必须在第一个 语句的相关性图的相加节点中插入X-和-指示指令,由于第二个语句 利用了第一个语句的结果,并且因此指示由第一个语句生成的异常 条件的任何特殊值将会被传递到第二个语句,所以通过在第二个语 句的相关性图中插入X-和-指示指令,在第二个语句的执行中对这些 特殊值进行检查就足够了。在所描述的例子中,插入X-和-指示指令 以使得捕获基本块中的所有活的值的最佳位置在第二个语句的相关 性图的存储指令st e[i]处。

因此,在异常覆盖的第一级别下,最少数目的X-和-指示指令被 插入到代码中。就代码的执行时间而言,这使得代码更有效,但是 只允许部分地检测某些异常条件。为了进一步说明这一点,考虑下 表:

  规则   运算   结果   1   N/0   无穷大   2   -N/0   -无穷大   3   无穷大+N   无穷大

  4   无穷大+无穷大   无穷大   5   -无穷大-无穷大   -无穷大   6   无穷大*N   无穷大   7   -无穷大*N   -无穷大   8   无穷大/N   无穷大   9   -无穷大/N   -无穷大   10   0/0   NAN   11   无穷大/无穷大   NAN   12   -无穷大/无穷大   NAN   13   无穷大-无穷大   NAN   14   无穷大*0   NAN

从这张表可见,对于许多运算,正的或者负的无穷大的输入可 能导致操作的输出是正的或者负的无穷大、或者非数值(NAN)。 例如,考虑加法运算,如“c[i]=(a[i]-1)+(b[i]-1)”。根据上面的规 则3,将一个有限的正数N加到无穷大得到无穷大;同样地,根据 上面的规则4,把无穷大加到无穷大也得到无穷大。但是,根据上面 的规则13,将负无穷大加到正无穷大的结果是NAN。因此,如果用 户期望报告适当的异常,即如果用户期望程序在遇到无穷大的数时 报告无穷大的异常,当遇到NAN数值时报告NAN异常,检查正在 存储的值(在上例中为“c[i]”)是不够的,因为当事实上“(a[i]-1)” 可能已经是正无穷大且“(b[i]-1)”可能已经是负无穷大时,存储和 指示操作可能报告NAN值。因此,在这种情形下,为了真实地报告 异常,除了运算的输出外(因为加到非常大的有限数可能导致产生 一个正无穷大数的表示),还必须检查加法运算的输入(以确保没 有NAN和/或正的/负的无穷大)。将这与仅检查NAN相比,因为任 一输入为NAN的加法都导致NAN数值,所以在加法之后检查异常 是足够的,因为在上例中值正被存储在“c[i]”中。

如上所记载的,异常覆盖的第二级别也是可能的,其中提供完 全的异常覆盖,也即,示例的机制检测所有的下溢和上溢异常条件。 利用异常覆盖的第二级别,在可能生成下溢、上溢或NAN条件的每 个计算之后,执行对指示异常条件的特殊值的检查。例如,算术运 算可以生成这些特殊异常条件和值,但是其他操作,例如选择、对 齐、比较和逻辑运算不生成这些特殊异常和值。

图13A-图13C是说明根据此其他示例的用于插入指示指令的插 入位置的示例图,在该示例中,期望异常覆盖的第二级别。图13A- 图13C所示的例子用于和图12A-图12C所示的相同的语句和基本 块,因此,相关性图是相同的。此外,图13A和图13B产生类似的 插入X-和-指示指令的插入点,因为,在图13A中,语句不涉及计算; 在图13B的例子中,在异常覆盖的第二级别下执行插入的“相加” 计算点与在其标准下针对异常覆盖的第一级别执行插入的点是相同 的点。在图13C所展示的例子中则产生不同,其中存在两个插入点, 而不是图12C所示的一个插入点。因为在第一相关性图中存在计算, 因此在第一相关性图中的“相加”指令节点处识别出用于添加X-和- 指示指令的附加的插入点,该第二插入点是存储st e[i],这类似于异 常覆盖的第一级别的实施例。

如上所述,在诸如语句、基本块等工作单元的相关性图中没有 位置是可检查的情形下,可以执行某些转换来将不可检查位置转换 为可检查位置。如上所述,一个转换是使用掩码来屏蔽向量寄存器 中的不可检查值,然后检查其他值。另一个转换可能包括禁用不可 检查值的SIMD向量化,将循环分割成若干的循环以将可检查的和 不可检查的语句聚集在一起。例如,循环脱皮操作可以用于把涉及 不可检查值的循环迭代中从涉及可检查值的循环迭代中剥落出来。 当读取-修改-写入位于循环的开头和/或结尾时,这一情形可能出现, 例如上面图11C所描述的。

在异常覆盖的第三级别,异常覆盖的前两个级别的任一个可以 被利用并且利用经验性确定来增强,该经验性确定关于不可检查值 是否是已知很少排除的。也就是说,可以预测性地检查不可检查值 并使用自定义的无效值异常处理机,此无效值异常处理机检测实际 异常是否发生或者异常是否是由于检查在第一个位置中不应当被检 查的值而造成的虚假异常。如果是后者这种情形,那么向量输出寄 存器可以被无效值异常处理机视为可检查的,相反,如果不可检查 值导致实际异常,那么向量输出寄存器中的不可检查部分被视为标 量,并且在此向量输出寄存器上的指令的SIMD执行被从SIMD转 换回标量执行。

无效值异常处理机可以检测这种异常在何处发生,计算掩码以 确定寄存器中的哪些异常可以作为虚假的而被忽略以及哪些不能忽 略。如果异常是虚假的,则无效值异常处理机继而可以返回到应用, 或者如果异常不是虚假的则报告异常。考虑如上考虑的同一例子, 即c[i]=(a[i]-1)+(b[i]-1)。如上讨论的,为了提供报告所有正无穷大 和负无穷大的异常覆盖的第二级别,插入两个移动-和-指示指令以检 查不存在“a[i]-1”可以是正无穷大和“b[i]-1”可以是负无穷大(或 者相反)的情形。回想对这一情形进行测试是必要的,因为将正无 穷大加到负无穷大产生NAN,这导致和正无穷大或负无穷大不同的 异常。现在,进一步假设这种情形实际上是非常稀少的,其中加法 的一个输入是正无穷大,加法的另一个输入是负无穷大。在这种情 形下,能够确定在“a[i]-1”和“b[i]-1”运算之后不添加此种检查, 只检查存储-和-指示的结果。现在,假定遇到了NAN异常,不知道 异常是归因于a[i]或者b[i]中的一个/两个是NAN而产生的还是归因 于正无穷大到负无穷大的加法产生的。在这种情形下,在异常覆盖 的第三级别下,异常处理机重放该计算,并且在每个步骤之后确定 是否计算了正无穷大、负无穷大或者NAN值。因此,利用这种方案, 可以以非常低的成本达到同样水平的异常报告级别,假设开始时这 些异常非常稀少。

应当注意,可以在启动源代码或者至少部分源代码的编译之前, 将期望的异常覆盖的特定级别作为配置参数而传递到编译器。例如, 用户通过向编译器传递参数值可以指定期望的异常覆盖的级别,编 译器然后选择应用到工作单元的适当的逻辑,编译器基于该参数处 理工作单元。可替换地,基于与预定阈值相比的预测的或者根据经 验确定的工作单元的执行次数,编译器可以动态选择要使用哪个异 常覆盖的级别。例如,当与原始标量代码相比时,编译器可以估计 执行修改的SIMD代码所需的处理器周期的数目,如果差别大于预 定的阈值,例如,百分比差别大于可接受的百分比,那么可以使用 异常覆盖的不同级别,期望其达到处理器周期更有效的结果。

因此,利用示例的机制,在优化和编译为标量执行而编写的原 始源代码时,编译器可以利用如上描述的多种异常推迟机制和在适 合于检查指示已经发生的被推迟的异常条件的特殊值之处插入X-和 -指示指令来将原始源代码转换成SIMD向量化代码。编译器可以利 用如上所述的任意一种或者多种机制的组合来实现代码的优化性 能。特别地,编译器可以利用实现以上关于图10-图13C所概述的一 个或多个机制的逻辑来选择工作单元中用于插入检查指示推迟的异 常的特殊值的X-和-指示指令的插入点。插入点的这种选择利用了如 上所述的“活的”值、“可检查的”和“不可检查的”或“非可检 查的”值的定义。

如上所述,应当理解,示例可以采取全部硬件实现、全部软件 实现或者包含硬件和软件元素两者的实现的形式。在一个实施例中, 示例的机制可以实施为软件或程序代码,其包括但不限于固件、常 驻软件、微代码等。

适合存储和/或执行程序代码的数据处理系统将包括至少一个 通过系统总线直接或间接到存储器元件的处理器。存储器元件可以 包括在程序代码的实际执行期间使用的局部存储器、大容量存储和 高速缓冲存储器,高速缓冲存储器对至少部分程序代码提供临时存 储,以减少在执行过程中代码必须从大容量存储器检索的次数。

输入/输出或者I/O设备(包括但不限于键盘、显示器、定点设 备等)或者直接或者通过干预I/O控制器耦合到系统。网络适配器也 可以耦合到系统,使的数据处理系统可以通过干预私有或公共网络 耦合到其他数据处理系统或者远程打印机或存储设备。调制解调器、 电缆调制解调器和以太网卡只是目前网络适配器几个可用类型。

本发明的说明书是用于例示和说明的目的所呈现的,并非意在 以公开的形式穷举或者限定本发明。对于本领域普通技术人员来说, 许多修改和变化将是显而易见的。所选择和描述的实施例是为了更 好地解释本发明的原理、实际应用,并且使得本领域技术人员能够 理解本发明在被适于预期的特殊用途时具有各种修改的各种实施 例。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号