歷史
1996年Intel首先推出了支持MMX的Pentium處理器,極大地提高了CPU處理多媒體數據的能力,被廣泛地套用於語音合成、語音識別、音頻視頻編解碼、圖像處理和流媒體等領域。但是MMX只支持整數運算,浮點數運算仍然要使用傳統的x87協處理器指令。
由於MMX與x87的暫存器相互重疊,在MMX代碼中插入x87指令時必須先執行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!。
技術討論
AMD的K6-2,是世界上第一個針對3D運算所需要的SI
MD-FP、MMX等加速特性,以硬體線路作出來的X86CPU。在當初Intel發表的MMX架構只能處理整數,對於3D的影像世界中,大量涌至的坐標轉換或數學函式的浮點運算完全幫不上忙,所以3D程式必須藉助CPU的浮點運算電路,有些還得藉助3D加速卡來計算。
糟糕的是MMX運算區域在規劃上,跟浮點運算的區域重疊,不論軟體正在做MMX運算或是浮點運算,都必須使用到這個區域,兩種運算形態不能同時存在,因此從MMX與CPU指令過於頻繁的切換,反而把MMX加速所省下來的時間來給抵消掉了。
AMD於是將MMX運算架構重新規劃改良,加入浮點運算的能力,使得MMX暫存器同時做整數與浮點運算,不但不用頻頻切換,而且MMX架構的SIMD特性能夠同時處理多筆浮點運算,還能大幅提升自家CPU的浮點效能!這正是AMD3DNow!技術的由來。
3DNow!架構
在AMD的規劃中,3DNow!技術由新改良的八組AMD3D運算暫存器,也就是由原先MMX暫存器所延伸而成的設計。MMX運算區域有64位寬度,可拆成八個位組、四組16位字(word)、兩組32位的長整數,而AMD最特別的還可以拆成兩組的32位浮點數,具備24位元的單精確度(SinglePrecision),差不多是小數點後七位數的精確度(最大誤差值約3300萬分之一)。
透過MMX/AMD3D的SIMD特性,在最佳化的程式碼執行狀態下,AMDK6-2一個周期內能處理四個浮點運算值,或者在幾個周期內做八組、十六個浮點整數資料的直接累加、累乘,浮點運算速度比原來用X87FPU快上幾倍到幾十倍!
3DNow!性能初體驗
以往3D影像處理,需要強悍的浮點運算能力,這正是Intel以外的CPU最弱的一環。也因此AMD決定以SIMD的特性,作出3DNow!的技術。如果將硬體平台,除CPU因PentiumⅡ與K6-2不同而搭配相異的主機板外,其餘像記憶體、硬碟盤、顯示卡(還是用Intel最引以為傲的i740)都是同一
組配備,而工作時鐘、外頻也都維持一致。
MaruBench測試實測結果顯示,300MHzK6-2的3D影像產生速率,遠遠超越300、500,甚至400MHz的PentiumⅡ,如果遊戲發展廠商,顯示卡開發廠商,肯及早支持AMD3DNow!技術,稍微改寫一下遊戲程式碼、顯示卡驅動程式的浮點運算部分,使用AMD-3D指令集去運算的話,就能提升
接近三倍到四倍的效能。
可怕的利齒,SharpToothAMDK6-3。
很快,Super7架構(100MHzSocket7+AGP主機板)即將出現天王巨星級的CPU,這就是研發代號為SharpTooth的K6-3。K6-3最大的賣點,就是內建256KL2Cache於CPU核心,而且運作速度跟CPU時鐘同步,這樣主機板上的FrontSizeL2Cache,就變成了L3Cache,這一招正是學自DECAlpha高速CPU三個階段快取架構。
執行環境
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。