X86 彙編/AVX、AVX2、FMA3、FMA4
外觀
< X86 彙編
先決條件:X86 彙編/SSE.
以下程式展示了 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+12與v4+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)
- 虛擬機器(為 Ubuntu 預先構建)和 VM 快照,用於在舊版 CPU 上測試新指令
- IEEE 754 單精度互動式小程式
- Intel AVX 簡介
- Binutils 測試套件(用於 AT&T 和 Intel 語法中的 AVX 和 FMA 示例)
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/fma.s;hb=HEAD
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/fma4.s;hb=HEAD
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/avx.s;hb=HEAD
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/avx-gather.s;hb=HEAD
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/avx2.s;hb=HEAD
- http://sourceware.org/git/?p=binutils.git;a=blob_plain;f=gas/testsuite/gas/i386/avx256int.s;hb=HEAD