3DNow!

3DNow。(据称是“3D No Waiting!”的缩写)是由AMD开发的一套SIMD多媒体指令集,支持单精度浮点数的矢量运算,用于增强x86架构的计算机在三维图像处理上的性能。

1996年Intel首先推出了支持MMX的Pentium处理器,极大地提高了CPU处理多媒体数据的能力,被广泛地应用于语音合成、语音识别、音频视频编解码、图像处理和流媒体等领域。但是MMX只支持整数运算,浮点数运算仍然要使用传统的x87协处理器指令。

由于MMX与x87的寄存器相互重叠,在MMX代码中插入x86指令时必须先执行EMMS指令清除MMX状态,频繁地切换状态将严重影响性能。这限制了MMX指令在需要大量浮点运算的程序,如三维几何变换、裁剪和投影中的应用。

另一方面,由于x87古怪的栈式寄存器结构,使得硬件上将其流水线化和软件上合理调度指令都很困难,这成为提高x86架构浮点性能的一个瓶颈。

为了解决以上这两个问题,AMD公司于1998年推出了包含21条指令的3DNow!指令集,并在其K6-2处理器中实现。K6-2是第一个能执行浮点SIMD指令的x86处理器,也是第一个支持平坦浮点寄存器模型的x86处理器。借助3DNow!,K6-2实现了x86处理器上最快的浮点单元,在每个时钟周期内最多可得到4个单精度浮点数结果,是传统x87协处理器的4倍。许多游戏厂商为3DNow!优化了程序,微软的DirectX 7也为3DNow!做了优化,AMD处理器的游戏性能第一次超过Intel,这大大提升了AMD在消费者心目中的地位。K6-2和随后的K6-III成为市场上的热门货。

1999年,随着AMD Athlon处理器的推出,AMD为3DNow!增加了5条新的指令,用于增强其在DSP方面的性能,它们被称为“扩展3DNow!”(Extended 3DNow!)。

为了对抗3DNow!,Intel公司于1999年推出了SSE指令集。SSE几乎能提供3DNow!的所有功能,而且能在一条指令中处理两倍多的单精度浮点数;同时,SSE完全支持IEEE 754,在处理单精度浮点数时可以完全代替x87。这迅速瓦解了3DNow!的优势。

1999年后,随着主流操作系统和软件都开始支持SSE并为SSE优化,AMD在其2000年发布的代号为“Thunderbird”的Athlon处理器中添加了对SSE的完全支持(“经典”的Athlon或K7只支持SSE中与MMX有关的部分,AMD称之为“扩展MMX”即Extended MMX)。随后,AMD致力于AMD64架构的开发;在SIMD指令集方面,AMD跟随Intel,为自己的处理器添加SSE2和SSE3支持,而不再改进3DNow!。

3DNow!指令的执行环境与MMX一样,都是将8个x87寄存器ST0~ST7的低64位重命名为MMX寄存器MM0~MM7,并依平坦模式进行操作(即指令可以任意访问这8个寄存器中的任何一个而不必使用堆栈)。

由于3DNow!使用的寄存器与x87寄存器重叠,任务切换时,保存x87寄存器状态的同时也保存了3DNow!的状态,所以3DNow!不需要操作系统的额外支持。只要CPU支持3DNow!,含有3DNow!代码的程序可以在只考虑到x87状态的原有的操作系统上不加修改地运行。

3DNow!和扩展3DNow!的26条指令从功能上可以分为以下五类:

单精度浮点运算指令

此类指令的操作数均为64位,其高32位和低32位分别是IEEE 754格式的单精度浮点数。大部分指令一次可接受两个这样的操作数,并得到两个单精度浮点数的结果。它们的汇编语言助记符都以PF开头。

3DNow!还包含有计算单精度倒数和开方倒数的指令,并可以依程序需要,得到12位精度和24位精度的结果。这些指令一次只能处理一个单精度浮点数。

增强的MMX指令

PAVGUSB用于求64位紧缩字节(8×8位字节)的平均值,可用于视频编码中的像素平均和图像缩放等。可能是意识到这个功能的重要性,Intel在SSE中添加了功能完全相同的PAVGB指令。

PMULHRW则用来补充MMX指令PMULHW的不足,在紧缩无符号字(4×16位字)相乘时可以得到比后者更准确的结果。

数据类型转换指令

PF2ID、PI2FD等4条指令用于完成整数和单精度浮点数之间的相互转换。

数据预取指令

PREFETCH/PREFETCHW指令用于把将要使用到的数据从主存提前装入缓存中,以减少访问主存的指令执行时的延迟。Intel在SSE中添加了类似的PREFETCHTx指令

快速退出MMX状态指令

FEMMS指令与MMX中的EMMS功能相同,用于退出MMX状态。在K6-2和K6-III处理器中,FEMMS比EMMS更快;在Athlon及更新的处理器中,FEMMS等同于EMMS。

作为AMD处理器历史上最古老的多媒体指令集,3DNow!正在和我们挥手告别,未来的特定AMD处理器将不再提供支持。

AMD通过官方博客宣布,这些新处理器中将不会再设置“3DNow! Instructions”的功能标志位,也就是CPUID扩展功能字的第31位不再为1。开发人员今后必须在使用之前首先检查当前处理器是否还支持3DNow!,避免导致程序运行失败,如需要相关指令可应用更新的SSE系列指令集。

不过例外的是,3DNow!版本的PREFETCH、PREFETCHW指令已经自成一体,AMD也计划今后继续提供支持。它们在CPUID规范中的功能标志位是3DNowPrefetch。

但是AMD并没有公布具体哪些处理器将会放弃支持3DNow!,估计会涉及即将推出的Fusion APU加速处理器和“推土机”架构产品。

3DNow!指令集简史:

1996年,Intel Pentium处理器率先加入了MMX指令集,极大地提高了多媒体处理能力,但仅支持整数运算,浮点运算仍然要使用传统的x87协处理器指令。随后在1998年,AMD推出了包含21条新指令的3DNow!指令集(据说是3D No Waiting!的缩写),并用于其K6-2处理器,使之成为第一个能够执行浮点SIMD指令的x86处理器,实现了x86架构下最快的浮点单元,四倍于x87协处理器。

3DNow!指令集赢得了业界的广泛支持,包括微软DX7都对其进行了优化,AMD处理器的游戏性能得以第一次超越Intel,K6-2和随后的K6-III成为市场上的热门产品。

1999年,AMD Athlon处理器发布,3DNow!指令集也增加了5条新指令,成为扩展3DNow!,但是同年Intel又推出了SSE指令集,在提供3DNow!几乎所有功能的同时大大提高了单精度浮点处理速度,还完全支持IEEE754标准,3DNow!优势不再。

之后主流操作系统和软件都开始支持SSE指令集并为其优化,AMD 2000年的新款Athlon处理器(代号雷鸟)中也加入了SSE。之后的时间里,AMD开始致力于AMD64架构的开发,SIMD指令集方面则跟随Intel,连续添加了SSE2、SSE3,不再改进3DNow!。

相关词汇

AMD
SIMD
多媒体指令集
单精度浮点数
多媒体指令集
语音合成
语音识别
流媒体
协处理器
寄存器
MMX指令
浮点运算
3DNow!指令集
浮点寄存器
单精度浮点数
协处理器
AMD处理器
SSE指令集
指令集
堆栈
寄存器
操作数
操作数
助记符
图像缩放
缓存
多媒体指令集
处理器
指令集
推土机
浮点运算
协处理器
微软
IEEE754标准
指令集
电脑版