跳轉到內容

X86 彙編/AVX、AVX2、FMA3、FMA4

來自華夏公益教科書,開放的書籍,開放的世界

先決條件:X86 彙編/SSE.

FMA4 程式示例

[編輯 | 編輯原始碼]

以下程式展示了 FMA4 指令的使用vfmaddps它可以用於在一行指令中執行 8 個單精度浮點乘加運算。

.data
        #          2^-1  2^-2  2^-3   2^-4    2^-5     2^-6      2^-7       2^-8
        v1: .float 0.50, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625
        v2: .float 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0
        v3: .float 512.0, 1024.0, 2048.0, 8192.0, 16384.0, 32768.0, 65536.0, 131072.0
        v4: .float 0,0,0,0,0,0,0,0
.text
.globl _start
        _start:
        vmovups v1,%ymm0
        vmovups v2,%ymm1
        vmovups v3,%ymm2
        #        addend + multiplicant1   * multiplicant2   = destination
        vfmaddps %ymm0,   %ymm1,            %ymm2,            %ymm3
        vmovups %ymm3, v4

如果在最後一行程式碼後設置斷點,可以使用 GDB 分析結果。檢視程式並嘗試找出任何問題。

劇透警告。以二進位制形式轉儲結果“向量”,我們可以看到精度已經丟失。

(gdb) x/8t &v4
0x80490fc <v4>:    01000100100000000001000000000000	01000101100000000000001000000000	01000110100000000000000001000000	01001000000000000000000000000100
0x804910c <v4+16>: 01001001000000000000000000000000	01001010000000000000000000000000	01001011000000000000000000000000	01001100000000000000000000000000
(gdb)

比較v4+12v4+16,可以看出加數變得太小,丟失了。我們只是將其從 +12 減半到 +16,為什麼現在沒有了?原因是指數也發生了改變,因此加數將放置在比前一個尾數的最後一個設定位少一位的位數上。因此,它變得非常小,以至於 32 位單精度浮點數無法表示它。當以其基數 10 表示形式轉儲浮點數時,資料丟失也可見,但需要注意,因為基數 10 表示形式並不總是忠實的。

(gdb) x/8f &v4
0x80490fc <v4>:    1024.5	4096.25	16384.125	131072.062
0x804910c <v4+16>: 524288	2097152	8388608		33554432
(gdb)
華夏公益教科書