国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

x86平臺SIMD編程入門(3):浮點指令

這篇具有很好參考價值的文章主要介紹了x86平臺SIMD編程入門(3):浮點指令。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1、算術(shù)指令

算術(shù)類型 函數(shù)示例 備注
_mm_add_sd、_mm256_add_ps
_mm_sub_sd、_mm256_sub_ps
_mm_mul_sd_mm256_mul_ps
_mm_div_sd、_mm256_div_ps
平方根 _mm_sqrt_sd_mm256_sqrt_ps
倒數(shù) _mm_rcp_ss、_mm_rcp_ps、_mm256_rcp_ps 快速計算32位浮點數(shù)的近似倒數(shù)(1/x),最大相對誤差小于\(1.5\times 2^{-12}\)。
倒數(shù)平方根 _mm_rsqrt_ss、_mm_rsqrt_ps、_mm256_rsqrt_ps 快速計算32位浮點數(shù)的近似倒數(shù)平方根(1/sqrt(x)),最大相對誤差小于\(1.5\times 2^{-12}\)。
水平加 _mm_hadd_ps、_mm256_hadd_pd 輸入兩個寄存器[a, b, c, d]和[e, f, g, h],返回[a+b, c+d, e+f, g+h]。
水平減 _mm_hsub_ps、_mm256_hsub_pd 輸入兩個寄存器[a, b, c, d]和[e, f, g, h],返回[a-b, c-d, e-f, g-h]。
交替加減 _mm_addsub_ps、_mm256_addsub_pd 輸入兩個寄存器[a, b, c, d]和[e, f, g, h],返回[a-e, b+f, c-g, d+h]。對于復(fù)數(shù)乘法比較有用。
點乘 _mm_dp_ps_mm_dp_pd、_mm256_dp_ps 輸入兩個寄存器和一個8位常量,常量高4位表示需要點乘的通道,低4位表示需要廣播結(jié)果的通道。
四舍五入 _mm_round_ps、_mm_floor_ss、_mm256_ceil_pd
最大/最小值 _mm_min_ss_mm256_max_pd

x86 SIMD指令中沒有一元減號或絕對值指令,但可以通過位操作技巧來實現(xiàn)對應(yīng)的功能,例如_mm_xor_ps(x, _mm_set1_ps(-0.0f))可實現(xiàn)一元減號運算,_mm_andnot_ps(_mm_set1_ps(-0.0f), x)可實現(xiàn)取絕對值。(因為-0.0f浮點數(shù)值只把符號位設(shè)置為1,其余位均為0,所以_mm_xor_ps會翻轉(zhuǎn)符號,_mm_andnot_ps會清除符號位。)

2、比較指令

SSE實現(xiàn)了各種浮點數(shù)比較運算,如下表所示:

運算符 函數(shù)示例
等于 _mm_cmpeq_ss、_mm_cmpeq_ps、_mm_cmpeq_sd、_mm_cmpeq_pd
小于 _mm_cmplt_ss、_mm_cmplt_ps_mm_cmplt_sd、_mm_cmplt_pd
小于等于 _mm_cmple_ss、_mm_cmple_ps、_mm_cmple_sd、_mm_cmple_pd
大于 _mm_cmpgt_ss、_mm_cmpgt_ps_mm_cmpgt_sd、_mm_cmpgt_pd
大于等于 _mm_cmpge_ss_mm_cmpge_ps、_mm_cmpge_sd_mm_cmpge_pd
不等于 _mm_cmpneq_ss、_mm_cmpneq_ps_mm_cmpneq_sd、_mm_cmpneq_pd
不小于 _mm_cmpnlt_ss_mm_cmpnlt_ps、_mm_cmpnlt_sd、_mm_cmpnlt_pd
不小于等于 _mm_cmpnle_ss、_mm_cmpnle_ps、_mm_cmpnle_sd_mm_cmpnle_pd
不大于 _mm_cmpngt_ss、_mm_cmpngt_ps_mm_cmpngt_sd、_mm_cmpngt_pd
不大于等于 _mm_cmpnge_ss_mm_cmpnge_ps、_mm_cmpnge_sd_mm_cmpnge_pd

AVX將浮點數(shù)比較指令統(tǒng)一成了_mm_cmp_xx_mm256_cmp_xx這樣的形式,然后通過一個常量來表示比較謂語。比較謂語如下表所示,兩個數(shù)比較時若其中一個數(shù)為NaN,則ordered模式將返回false,unordered模式將返回true,另外signalling只影響MXCSR的值。

比較運算 ordered (non-signalling) unordered (non-signalling) ordered (signalling) unordered (signalling)
a < b _CMP_LT_OQ _CMP_NGE_UQ _CMP_LT_OS _CMP_NGE_US
a <= b _CMP_LE_OQ _CMP_NGT_UQ _CMP_LE_OS _CMP_NGT_US
a == b _CMP_EQ_OQ _CMP_EQ_UQ _CMP_EQ_OS _CMP_EQ_US
a != b _CMP_NEQ_OQ _CMP_NEQ_UQ _CMP_NEQ_OS _CMP_NEQ_US
a >= b _CMP_GE_OQ _CMP_NLT_UQ _CMP_GE_OS _CMP_NLT_US
a > b _CMP_GT_OQ _CMP_NLE_UQ _CMP_GT_OS _CMP_NLE_US
true _CMP_ORD_Q _CMP_TRUE_UQ _CMP_ORD_S _CMP_TRUE_US
false _CMP_FALSE_OQ _CMP_UNORD_Q _CMP_FALSE_OS _CMP_UNORD_S

浮點數(shù)比較指令返回另一個寄存器來保存結(jié)果,其中比較條件成立的值賦為全1(NaN),其它賦為全0(0.0f)。可以使用_mm_movemask_ps、_mm_movemask_pd或AVX中的等效指令來將結(jié)果發(fā)送到CPU通用寄存器,這些指令收集每個浮點數(shù)通道的最高有效位(恰好也是符號位)并打包成標(biāo)量,然后復(fù)制到通用寄存器中。

const __m128 zero = _mm_setzero_ps();
const __m128 eq = _mm_cmpeq_ps(zero, zero);
const int mask = _mm_movemask_ps(eq);
printf("%i\n", mask);

在上面這段代碼中,對于__m128的所有4個通道,0 == 0的比較結(jié)果都是正確的,eq變量的所有128位都設(shè)置為1,然后_mm_movemask_ps收集并返回所有4個浮點數(shù)通道的符號位,最終打印出的mask值是15,即二進制的0b1111。比較結(jié)果的另外一些用途,就是可以將它們作為其它指令的參數(shù)(例如blendv指令)。

除了全通道比較函數(shù)外,也有一些函數(shù)可以只比較兩個寄存器的最低通道,如下表所示:

運算符 函數(shù)示例
等于 _mm_comieq_ss_mm_comieq_sd
不等于 _mm_comineq_ss、_mm_comineq_sd
小于 _mm_comilt_ss_mm_comilt_sd
小于等于 _mm_comile_ss、_mm_comile_sd
大于 _mm_comigt_ss_mm_comigt_sd
大于等于 _mm_comige_ss、_mm_comige_sd

3、洗牌指令

3.1、固定順序洗牌

函數(shù)示例 說明 示意圖
_mm_movehl_ps 將向量a中的高2個元素復(fù)制到dst的高2個元素中,將向量b中的高2個元素復(fù)制到dst的低2個元素中。 x86平臺SIMD編程入門(3):浮點指令
_mm_movelh_ps 將向量a中的低2個元素復(fù)制到dst的低2個元素中,將向量b中的低2個元素復(fù)制到dst的高2個元素中。 x86平臺SIMD編程入門(3):浮點指令
_mm_unpacklo_ps 取向量a和向量b的低半部分元素并交錯存儲到dst中。 x86平臺SIMD編程入門(3):浮點指令
_mm_unpackhi_ps 取向量a和向量b的高半部分元素并交錯存儲到dst中。 x86平臺SIMD編程入門(3):浮點指令
_mm_movehdup_ps 復(fù)制輸入向量中的奇數(shù)索引元素,并存儲到dst中。 x86平臺SIMD編程入門(3):浮點指令
_mm_moveldup_ps 復(fù)制輸入向量中的偶數(shù)索引元素,并存儲到dst中。 x86平臺SIMD編程入門(3):浮點指令
_mm_broadcastss_ps 將輸入向量的最低通道元素廣播到dst的所有元素中。 x86平臺SIMD編程入門(3):浮點指令

3.2、編譯時洗牌

這類函數(shù)都接收一個編譯期確定的常量來控制洗牌順序,如果傳入的控制系數(shù)無法在編譯期確定,那么將導(dǎo)致編譯錯誤,例如:

const __m128 zero = _mm_setzero_ps();
_mm_shuffle_ps(zero, zero, rand()); //error C2057: expected constant expression

下表僅列舉了一些參數(shù)是__m128類型的洗牌函數(shù),__m128d、__m256、__m256d也都有對應(yīng)的函數(shù),可以類推。示意圖中藍(lán)色箭頭表示使用控制系數(shù)選擇的內(nèi)容,灰色箭頭表示不同控制系數(shù)可能選擇的內(nèi)容。

函數(shù)示例 說明 示意圖
_mm_shuffle_ps 右圖中,控制常數(shù)是0x98(二進制 10 01 10 00)。輸出向量的前2個通道來自第一個輸入向量的0b00和0b10號通道,后2個通道來自第二個輸入向量的0b01和0b10號通道。如果要對單個向量進行置換,可將兩個輸入向量都設(shè)為同一個向量??梢允褂煤?code>_MM_SHUFFLE來生成控制常數(shù)。 x86平臺SIMD編程入門(3):浮點指令
_mm_blend_ps 右圖中,控制常數(shù)為1(二進制 0 0 0 1),所以只從第二個輸入向量中提取了對應(yīng)的0號通道,其余通道都取自第一個輸入向量的對應(yīng)通道。 x86平臺SIMD編程入門(3):浮點指令
_mm_insert_ps 插入單個通道,并可選擇將某些通道清零。右圖中,控制常數(shù)為0x61(二進制 01 10 0001):源索引為0b01,目標(biāo)索引為0b10,所以第二個輸入向量中0b01號通道的F被插入了輸出的0b10號通道;最低4位為0b0001,因此0號輸出通道被清零。此外,我們也可以選擇性地將某些通道清零而無需插入,例如控制常數(shù)0b00001001將0號和3號通道清零。(也可以使用_mm_blend_ps_mm_setzero_ps實現(xiàn)等價功能,但這就是兩條指令,而不是一條。) x86平臺SIMD編程入門(3):浮點指令
_mm_permute_ps _mm_shuffle_ps類似,區(qū)別在于僅對一個輸入向量進行洗牌。右圖中,控制常數(shù)是0x63(二進制 01 10 00 11)。 x86平臺SIMD編程入門(3):浮點指令

3.3、運行時洗牌

_mm_blendv_ps、_mm_blendv_pd、_mm256_blendv_ps_mm256_blendv_pd接收3個參數(shù),通過掩碼的符號位從向量a或向量b中選擇通道。

_mm_permutevar_ps_mm256_permutevar8x32_ps都接收一個包含源數(shù)據(jù)的浮點數(shù)寄存器和一個包含源索引的整數(shù)寄存器,根據(jù)整數(shù)寄存器中的索引值從浮點數(shù)寄存器中選擇通道。

4、乘加融合指令

乘加運算 函數(shù)示例
(a · b) + c _mm_fmadd_ps、_mm256_fmadd_pd
(a · b) - c _mm_fmsub_ps、_mm256_fmsub_pd
-(a · b) + c _mm_fnmadd_ps、_mm256_fnmadd_pd
-(a · b) - c _mm_fnmsub_ps、_mm256_fnmsub_pd

相較于分別使用乘法和加法指令,乘加融合(fused multiply-add, FMA)指令除了性能較高外,還更加精確,因為這些指令只在計算完乘法與加法后進行一次舍入。文章來源地址http://www.zghlxwxcb.cn/news/detail-741778.html

到了這里,關(guān)于x86平臺SIMD編程入門(3):浮點指令的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【ARMv8 SIMD和浮點指令編程】浮點數(shù)據(jù)轉(zhuǎn)換指令——數(shù)據(jù)類型互轉(zhuǎn)必備

    浮點數(shù)據(jù)轉(zhuǎn)換指令包括不同的浮點精度數(shù)之間的轉(zhuǎn)換,還包括整型和浮點數(shù)之間的轉(zhuǎn)化。 在了解數(shù)據(jù)轉(zhuǎn)換指令前,必須學(xué)習(xí) IEEE 754 定義的五種舍入規(guī)則。前兩條規(guī)則舍入到最接近的值,其他的稱為定向舍入: 舍入到最接近的值 Round to nearest, ties to even – rounds to the nearest va

    2024年02月02日
    瀏覽(26)
  • 【ARMv8 SIMD和浮點指令編程】浮點加減乘除指令——四則運算

    【ARMv8 SIMD和浮點指令編程】浮點加減乘除指令——四則運算

    浮點指令有專門的加減乘除四則運算指令,比如 FADD、FSUB、FMUL、FDIV 等。 1 FADD (scalar) 浮點加法(標(biāo)量)。該指令將兩個源 SIMDFP 寄存器的浮點值相加,并將結(jié)果寫入目標(biāo) SIMDFP 寄存器。 該指令可以產(chǎn)生浮點異常。根據(jù) FPCR 中的設(shè)置,異常會導(dǎo)致在 FPSR 中設(shè)置標(biāo)志,或者生成同

    2024年02月05日
    瀏覽(27)
  • 【ARMv8 SIMD和浮點指令編程】NEON 乘法指令——乘法知多少?

    【ARMv8 SIMD和浮點指令編程】NEON 乘法指令——乘法知多少?

    NEON 乘法指令包括向量乘法、向量乘加和向量乘減,還有和飽和相關(guān)的指令??傊朔ㄖ噶钍潜匦拚n,在我們的實際開發(fā)中會經(jīng)常遇到。 1 MUL (by element) 乘(向量,按元素)。該指令將第一個源 SIMDFP 寄存器中的向量元素乘以第二個源 SIMDFP 寄存器中的指定值,將結(jié)果放入向

    2024年02月08日
    瀏覽(26)
  • 【ARMv8 SIMD和浮點指令編程】NEON 通用數(shù)據(jù)處理指令——復(fù)制、反轉(zhuǎn)、提取、轉(zhuǎn)置...

    【ARMv8 SIMD和浮點指令編程】NEON 通用數(shù)據(jù)處理指令——復(fù)制、反轉(zhuǎn)、提取、轉(zhuǎn)置...

    NEON 通用數(shù)據(jù)處理指令包括以下指令(不限于): ? DUP 將標(biāo)量復(fù)制到向量的所有向量線。 ? EXT 提取。 ? REV16、REV32、REV64 反轉(zhuǎn)向量中的元素。 ? TBL、TBX 向量表查找。 ? TRN 向量轉(zhuǎn)置。 ? UZP、ZIP 向量交叉存取和反向交叉存取。 1 DUP (element) 將向量元素復(fù)制為向量或標(biāo)量。

    2024年02月07日
    瀏覽(23)
  • 【ARMv8 SIMD和浮點指令編程】NEON 存儲指令——如何將數(shù)據(jù)從寄存器存儲到內(nèi)存?

    【ARMv8 SIMD和浮點指令編程】NEON 存儲指令——如何將數(shù)據(jù)從寄存器存儲到內(nèi)存?

    和加載指令一樣,NEON 有一系列的存儲指令。比如 ST1、ST2、ST3、ST4。 1 ST1 (multiple structures) 從一個、兩個、三個或四個寄存器存儲多個單元素結(jié)構(gòu)。該指令將元素從一個、兩個、三個或四個 SIMDFP 寄存器存儲到內(nèi)存,無需交錯。每個寄存器的每個元素都被存儲。 無偏移 一個寄

    2024年02月07日
    瀏覽(27)
  • 【ARMv8 SIMD和浮點指令編程】NEON 加載指令——如何將數(shù)據(jù)從內(nèi)存搬到寄存器(其它指令)?

    【ARMv8 SIMD和浮點指令編程】NEON 加載指令——如何將數(shù)據(jù)從內(nèi)存搬到寄存器(其它指令)?

    除了基礎(chǔ)的 LDx 指令,還有 LDP、LDR 這些指令,我們也需要關(guān)注。 1 LDNP (SIMDFP) 加載 SIMDFP 寄存器對,帶有非臨時提示。該指令從內(nèi)存加載一對 SIMDFP 寄存器, 向內(nèi)存系統(tǒng)發(fā)出訪問是非臨時的提示 。用于加載的地址是根據(jù)基址寄存器值和可選的立即偏移量計算得出的。 32-bit (

    2024年02月07日
    瀏覽(27)
  • C# 使用SIMD向量類型加速浮點數(shù)組求和運算(5):如何查看Release程序運行時匯編代碼

    C# 使用SIMD向量類型加速浮點數(shù)組求和運算(5):如何查看Release程序運行時匯編代碼

    作者: zyl910 目錄 一、引言 二、辦法說明 2.1 基本辦法 2.2 Release程序如何設(shè)置斷點 2.3 如何避免“分層編譯”的誤導(dǎo) 2.4 實際演練(匯編調(diào)試) 2.4.1 進入斷點 2.4.2 單步調(diào)試 2.4.3 觀察主循環(huán)的匯編代碼 三、結(jié)語 參考文獻 前面的幾篇文章里,介紹了 C# 編寫向量算法的各種辦法

    2024年02月12日
    瀏覽(33)
  • C# 使用SIMD向量類型加速浮點數(shù)組求和運算(4):用引用代替指針, 擺脫unsafe關(guān)鍵字,兼談Unsafe類的使用

    作者: zyl910 目錄 一、引言 二、辦法說明 2.1 歷史 2.2 局部引用變量與引用所指的值(類似指針的 地址運算符 、間接運算符 * ) 2.3 重新分配局部引用變量(類似指針直接賦值) 2.4 引用地址調(diào)整(類似指針加減法) 2.5 引用地址比較(類似指針比較) 2.6 重新解釋(類似C++的

    2024年02月15日
    瀏覽(21)
  • (匯編) 基于VS的x86匯編基礎(chǔ)指令

    visual studio 選擇x86運行 示例代碼 OV 溢出 超出表示范圍為溢出 1,否則 0 UP 增量 1:以遞減順序?qū)?shù)據(jù)串處理;0:以遞增順序?qū)?shù)據(jù)串處理 EI 允許中斷 CPU允許中斷1,否則0 PL 正 運算結(jié)果為正則為1,否則0 ZR 零 運算結(jié)果為0則為1,否則0 AC 輔助進位 低4位向高位進位1,否則0 P

    2024年02月06日
    瀏覽(19)
  • x86匯編_MUL/IMUL乘法指令_筆記52

    x86匯編_MUL/IMUL乘法指令_筆記52

    32位模式下整數(shù)乘法可以實現(xiàn)32、16或8位的操作,64位下還可以使用64位操作數(shù)。MUL執(zhí)行無符號乘法,IMUL執(zhí)行有符號乘法。 MUL指令:無符號數(shù)乘法 32 位模式下,MUL(無符號數(shù)乘法)指令有三種類型: 執(zhí)行 8 位操作數(shù)與 AL 寄存器的乘法; 執(zhí)行 16 位操作數(shù)與 AX 寄存器的乘法;

    2024年02月07日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包